2013-03-12 11 views
10

ハスケルの関数アプリケーション演算子($)の周りを頭で囲んでいます。ハスケルで関数アプリケーション演算子を理解しようとしています

私はあなたにハスケルを学び、そして私は、次の例を理解する考えで例を挙げて取り組んでいます:

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機能は以下のバリアントは、[OK]を作品として、前のリストの要素に関連付けられて始まる何とかであればそれはそうです:

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

誰かがここで何が起こっているのかに関して、私を啓発することができますか?

+0

GHCiプロンプトで何か試した後、* type *を** Prelude:t it' **で確認してください。 "それ"は前の結果を参照する特別な単語で、 ':t'は型を見るように要求します。最後の例では、数値に小数点がないことがわかります。また、プロンプトで** ':s + t' **と入力すると、GHCiは生成するすべての結果のタイプを報告します。 –

答えて

17

使用指数演算子の種類は、あなたが\x -> 2^xを使用するときに、あなたが3ためIntegral制約を取得

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

です。しかし、sqrtFloatingという制約を課します。だから、3のタイプは

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

を満たさなければならないが、IntegerDoubleので、デフォルト化が失敗した、とあなたは曖昧な型変数を残しているデフォルトのタイプリスト、間の両方のためのインスタンスがありません。あなたは\x -> x^2たとき

は、そこだけ最初の関数からNum制約だった、とsqrtからFloating、その種類はDoubleにデフォルト設定されました。あなたは指数演算子として

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

を使用する場合は、それを動作させることができ

、その種類は再びDoubleにデフォルト設定することができます。

+3

それから、(^)を(**)に置き換えて修正することができました。 – zurgl

+0

DanielとZurglの両方に感謝します。 Pythonから来て、私は厳密な型チェックの意味を頭に入れています。 –