s id id idに型が付かない件について

s id id idに型が付かない.

ghci> let s f g h = f h $ g h
ghci> :t s id id id

<interactive>:1:5:
    Occurs check: cannot construct the infinite type: a = a -> b
    Probable cause: `id' is applied to too few arguments
    In the second argument of `s', namely `id'
    In the expression: s id id id

フンギャー

gosh> (define (s f g x) ((f x) (g x)))
s
gosh> (s values values values)
#<subr values>

Schemeなら問題なく動くのに!ムキー!
って考えてたらもっと短く,型が付かないコードを見付けた.

ghci> let w x = x x

<interactive>:1:10:
    Occurs check: cannot construct the infinite type: t = t -> t1
    Probable cause: `x' is applied to too many arguments
    In the expression: x x
    In the definition of `w': w x = x x

いや,待てよ.Haskellには魔法の関数 unsafeCoerce があるじゃないか!

ghci> import Unsafe.Coerce
ghci> let w' x = x $ unsafeCoerce x
ghci> (w' id :: a -> a) 42
42

これを使えばさっきの関数も…!

ghci> let s' f g h = f h $ unsafeCoerce $ g h
ghci> :t s'
s' :: (t -> b1 -> b) -> (t -> a) -> t -> b
ghci> (s' id id id :: a -> a) 42
42

動いた!わーい!

何かがおかしい…

ところで s'a -> a に特化した s'' を書こうと思ったのだが

ghci> let s'' f g h = s' f g h :: a -> a
<interactive>:1:16:
    Inferred type is less polymorphic than expected
      Quantified type variable `a' is mentioned in the environment:
        f :: t -> b1 -> a -> a (bound at <interactive>:1:8)
    In the expression: s' f g h :: a -> a
    In the definition of `s''': s'' f g h = s' f g h :: a -> a
ghci> let s'' f g h = s' f g h `asTypeOf` h
ghci> :t s''
s'' :: (t -> b1 -> t) -> (t -> a) -> t -> t
ghci> s'' id id id

<interactive>:1:4:
    Occurs check: cannot construct the infinite type: t = b1 -> t
    Probable cause: `id' is applied to too many arguments
    In the first argument of `s''', namely `id'
    In the expression: s'' id id id
ghci> let s'' :: (a -> a) -> (b -> b) -> (c -> c) -> c -> c; s'' f g h = s' f g h

<interactive>:1:54:
    Occurs check: cannot construct the infinite type: c = c -> c
    When generalising the type(s) for `s'''

分からん…