Skip to content

Instantly share code, notes, and snippets.

@lagenorhynque
Last active June 10, 2026 02:16
Show Gist options
  • Select an option

  • Save lagenorhynque/6579f7c816234add1e73a295936f631d to your computer and use it in GitHub Desktop.

Select an option

Save lagenorhynque/6579f7c816234add1e73a295936f631d to your computer and use it in GitHub Desktop.
Higher-rank polymorphism availability in Flix, Haskell, and Scala
// コンパイルできる
flix> def applyTwice(f: a -> a, x: a, y: a): (a, a) = (f(x), f(y))
Ok.
// コンパイルできない: 関数 needsRankN は a について多相だが、引数 f は単相である(そして多相にする手段が現状ない)ため
flix> def needsRankN(f: a -> a): (Int32, String) = (f(1), f("hello"))
-- Type Error [E7796] ------------------------------------------------------- $3
>> Unexpected type: expected 'Int32 -> a', found 'a -> a'.
1 | def needsRankN(f: a -> a): (Int32, String) = (f(1), f("hello"))
^^^^
unexpected type
-- Type Error [E6794] ------------------------------------------------------- $3
>> Unable to unify the types: 'Int32' and 'a'.
1 | def needsRankN(f: a -> a): (Int32, String) = (f(1), f("hello"))
^^^^
mismatched types.
Type One: Int32
Type Two: a
-- Type Error [E7796] ------------------------------------------------------- $3
>> Unexpected type: expected 'String -> a', found 'a -> a'.
1 | def needsRankN(f: a -> a): (Int32, String) = (f(1), f("hello"))
^^^^^^^^^^
unexpected type
-- Type Error [E6794] ------------------------------------------------------- $3
>> Unable to unify the types: 'String' and 'a'.
1 | def needsRankN(f: a -> a): (Int32, String) = (f(1), f("hello"))
^^^^^^^^^^
mismatched types.
Type One: String
Type Two: a
Compilation failed with 4 error(s).
Error: Declaration ignored due to previous error(s).
-- ref. https://wiki.haskell.org/Rank-N_types
λ> :{
λ| needsRankN :: (forall a. a -> a) -> (Int, String)
λ| needsRankN f = (f (1 :: Int), f "hello")
λ| :}
needsRankN :: (forall a. a -> a) -> (Int, String)
λ> needsRankN id
(1,"hello")
it :: (Int, String)
// ref. https://docs.scala-lang.org/scala3/reference/new-types/polymorphic-function-types.html
scala> def needsRankN(f: [A] => A => A): (Int, String) = (f(1), f("hello"))
def needsRankN(f: [A] => (x$1: A) => A): (Int, String)
scala> needsRankN([A] => (x: A) => x)
val res1: (Int, String) = (1, "hello")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment