Fof*_*Fof 0 haskell types unification
我试图理解为什么这两个评价:(init . cuts) [1,2,3]并且init . cuts [1,2,3]是不同的,其中:
cuts :: [a] -> [([a],[a])]
cuts xs = zipWith splitAt [0..length xs] (repeat xs)
Run Code Online (Sandbox Code Playgroud)
第一个给出了我预期的结果:[([],[1,2,3]),([1],[2,3]),([1,2],[3])],但是第二个返回此错误:
<interactive>:389:8:
Couldn't match expected type `a0 -> [a1]'
with actual type `[([a2], [a2])]'
In the return type of a call of `cuts'
Probable cause: `cuts' is applied to too many arguments
In the second argument of `(.)', namely `cuts [1, 2, 3]'
In the expression: init . cuts [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
我认为,这init . cuts [1,2,3] = init (cuts[1,2,3])是正确的吗?
谢谢,
塞巴斯蒂安.
这是因为固定性或操作顺序.当编译器看到
(init . cuts) [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
它将此解析为inits . cuts带参数的函数[1, 2, 3].当它看到
init . cuts [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
它将此解析inits为由函数组成的函数cuts [1, 2, 3],但由于cuts [1, 2, 3]它不是函数,因此会引发类型错误.这是因为函数应用程序总是优先于运算符应用程序.这就是为什么你可以编写类似的表达式
f = zipWith (+) [1..] . filter (< 10) . take 5
Run Code Online (Sandbox Code Playgroud)
代替
f = (zipWith (+) [1..]) . (filter (< 10)) . (take 5)
Run Code Online (Sandbox Code Playgroud)
如果运算符优先级可能高于函数应用程序优先级,那么您可能必须根据运算符优先级使用后一种形式,然后表达式变得更难以使编译器和程序员解析.这可能意味着可能存在类似的含糊之处
x 1 <#> y
Run Code Online (Sandbox Code Playgroud)
因为它可以被解析为
(x 1) <#> y
Run Code Online (Sandbox Code Playgroud)
要么
x (1 <#> y)
Run Code Online (Sandbox Code Playgroud)
取决于优先级(我只是组成了一个运算符<#>).
正如@chepner正确地指出的那样,如果你想避免使用括号(就像许多Haskeller那样),你可以使用$运算符,它具有精心选择的固定性,允许你做
init . cuts $ [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
用经验法则$ 操作是,它是相同的 具有相同的效果1作为采取任何出现在右边和在括号包裹它,使复杂表达式像
func (func (func (func (func 1))))
Run Code Online (Sandbox Code Playgroud)
可以改为以更好的形式编写
func $ func $ func $ func $ func 1
Run Code Online (Sandbox Code Playgroud)
甚至
func . func . func . func . func $ 1
Run Code Online (Sandbox Code Playgroud)
1正如@Cubic所指出的,有些人可能会认为这$是Haskell的一些特殊语法.不是这种情况.它的定义非常简单
($) :: (a -> b) -> a -> b
f $ x = f x
infixr 0 $
Run Code Online (Sandbox Code Playgroud)
实际上,这个函数与函数相同id,只是表示为一个具有非常低优先级的中缀运算符,它与右边相关联,并且该固定性使得运算符非常有用地表达代码非常干净.它可以等效于使用更多括号,但这并不能使它成为替代语法.这只是另一个功能.
| 归档时间: |
|
| 查看次数: |
80 次 |
| 最近记录: |