簡體   English   中英

試圖了解Haskell中的函數應用程序運算符

[英]Trying to understand function application operator in Haskell

我試圖在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]

最后,我嘗試按如下方式修改列表中的第三個函數,這會生成錯誤:

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函數以某種方式開始與前一個list元素相關聯,因為以下變體可以正常工作:

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

有人可以告訴我這里發生了什么嗎?

使用的取冪運算符的類型是

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

所以,當你使用\\x -> 2^x ,你會得到一個Integral的限制3 但是sqrt強加了一個Floating約束。 所以3的類型必須滿足

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

但是默認類型列表中沒有兩個實例,它們是IntegerDouble ,因此默認失敗,並且你留下了一個模糊的類型變量。

當你有\\x -> x^2 ,第一個函數只有一個Num約束,而從sqrt Floating ,所以類型默認為Double

如果使用,可以使它工作

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

作為你的指數運算符,那么類型可以再次默認為Double

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM