10

$Haskellの関数適用演算子 ( ) に頭を悩ませようとしています。

Learn You a Haskell の例に取り組んでいて、次の例を理解していると思いました。

Prelude> map ($ 3) [(+4), (*10), (^2), sqrt]
[7.0,30.0,9.0,1.7320508075688772] 

次に、次のバリアントを試しましたが、これも正常に機能しました。

Prelude> map ($ 3) [(+4), (*10), (\x -> x^2), sqrt]
[7.0,30.0,9.0,1.7320508075688772]

最後に、リストの 3 番目の関数を次のように変更しようとしましたが、エラーが発生しました。

Prelude> map ($ 3) [(+4), (*10), (\x -> 2^x), sqrt] 
<interactive>:53:38:
    Ambiguous type variable `b0' in the constraints:
      (Floating b0)
        arising from a use of `sqrt' at <interactive>:53:38-41
      (Integral b0) arising from a use of `^' at <interactive>:53:33
      (Num b0) arising from the literal `3' at <interactive>:53:8
    Probable fix: add a type signature that fixes these type variable(s)
    In the expression: sqrt
    In the second argument of `map', namely
      `[(+ 4), (* 10), (\ x -> 2 ^ x), sqrt]'
    In the expression: map ($ 3) [(+ 4), (* 10), (\ x -> 2 ^ x), sqrt]
Prelude> 

sqrt次のバリアントが正常に機能するため、最後の関数が何らかの形で前のリスト要素に関連付けられているようです。

Prelude> map ($ 3) [(+4), (*10), (\x -> 2^x)]
[7,30,8]

誰かがここで何が起こっているのか教えてもらえますか?

4

1 に答える 1

17

使用されるべき乗演算子の型は

(^) :: (Num a, Integral b) => a -> b -> a

したがって、 を使用すると、 の制約\x -> 2^xが得られます。しかし、制約を課します。したがって、3 の型は次を満たす必要があります。Integral3sqrtFloating

3 :: (Integral t, Floating t) => t

しかし、デフォルトの型リスト ( と ) には両方のインスタンスがないため、デフォルト設定はInteger失敗Doubleし、あいまいな型変数が残ります。

があったとき、最初の関数とからの制約\x -> x^2のみがあったため、型はデフォルトで に設定されました。NumFloatingsqrtDouble

使用すれば動作させることができます

(**) :: Floating a => a -> a -> a

を累乗演算子として使用すると、型は再びデフォルトで に設定できDoubleます。

于 2013-03-12T13:54:47.263 に答える