【发布时间】:2014-06-26 12:23:37
【问题描述】:
所以这不起作用:
take 50 iterate (* 2) 1
因为它需要在 take 的第二个参数中加上括号。我的问题是为什么。
Haskell 正确地看到了类型的差异:
Couldn't match expected type `[a0]'
with actual type (a1 -> a1) -> a1 -> [a1]'
我的问题是:
1) haskell 似乎首先尝试在 iterate 函数之前解析 take 50 函数。为什么haskell会这样做?在数学中,如果你有 f g t w u (x),你首先要评估 u(x),然后再做其他事情。在这种情况下,为什么haskell 从评估 f 开始?
2) Haskell 足够聪明,可以检测到实际类型是:
(a1 -> a1) -> a1 -> [a1]
现在,如果它看到这个函数的输出是[a1],一个可以和预期类型[a0]统一的类型,为什么haskell不统一呢?
3) 为什么 $ 运算符会解决这个问题?我知道:
($) :: (a -> b) -> a -> b
所以基本上这个操作符所做的就是说“write FUNCTION $ ARGUMENT”,然后你会得到在那个参数处评估的函数的值。在 take 50 的情况下,类型是:
take 50 :: [a2]->[a2]
take 50 $ :: a->b
where a ~a2 and b~b2 then
take 50 $ :: [a2]->[a2]
所以基本上我的情况与第一种情况相同,没有使用括号或 $。这种情况是我需要一个类型为 [a2] 的参数(haskell 称它为 [a0] 但它是相同的。所以.. 为什么 haskell 将 [a2] 与 (a1 -> a1) -> a1 -> [a1] 统一起来当我使用 $ 但我不使用它时它没有?
【问题讨论】:
-
“在数学中,如果你有 f g t w u (x),你首先要评估 u(x),然后再做其他事情。”呃……不是吗?并列通常意味着数学中的乘法,而它在 Haskell 中是函数应用。你有更好的例子吗?
-
我的意思是函数组合,键盘没有数学中使用的函数组合符号,虽然我同意我可以用点来暗示组合。
标签: function haskell operator-keyword infix-notation operator-precedence