2013-11-25 46 views
2

我的代码:哈斯克尔初学者顺序功能

isOrdered :: (a -> a -> Bool) -> [a] -> Bool 
isOrdered mark xs =(head xs) `mark`(head(tail xs)) 

编译完美,但是当我尝试

isOrdered < [1,2,3] 

调用它,我得到一个错误:

Couldn't match expected type `(a0 -> a0 -> Bool) -> [a0] -> Bool' 
      with actual type `[t0]' 
In the second argument of `(<)', namely `[1, 2, 3]' 
In the expression: isOrdered < [1, 2, 3] 
In an equation for `it': it = isOrdered < [1, 2, 3] 

我在想什么这里?

回答

2

这工作:

isOrdered (<) [1,2,3] 

不知道为什么,虽然。这是一个普遍的事情:

Prelude> :type < 
<interactive>:1:1: parse error on input `<' 
Prelude> :type (<) 
(<) :: Ord a => a -> a -> Bool 

我相信别人会解释。

2

当通过运营商向更高层次的功能,你必须用括号括起来:

isOrdered (<) [1, 2, 3] 

您还可以选择为部分应用的运营商

map (== 2) [1, 2, 3] 
+0

谢谢!我不知道我是怎么忘了那个...... –

5

做,因为<是缀,你必须把它包装在parens中。这将其转换为前缀。

1 < 2 ==> (<) 1 2 
1 + 5 ==> (+) 1 5 

那么你的代码变得

isOrdered (<) [1, 2, 3] 

这实际上是切片的更一般概念的一部分。您可以完全转换中缀运算符与括号的前缀或部分应用它这样

\x -> x + 1 ===> (+1) 
\x -> 2^x ===> (2^) 

这哪里去有点梨形是-唯一的地方。由于-是由Haskell语言定义的超级特殊前缀运算符,因此不能确定它是否为段或数字,因此不能执行(-2)。 Haskell选择一个数字,但如果你想要一个部分,有一个功能subtract

\x -> x - 2 ==> subtract 2 
+0

男人,一元'''是一个丑陋的黑客。我个人不介意把否定写成'0 - x'。 –

0

这不是一个回答你的问题,而只是一个文体提示:地道的Haskell代码应该使用模式匹配,而不是head/tail。模式匹配静态确保您不会意外尝试访问不存在的元素。

你会使用模式匹配写功能的方法是:

isOrdered :: (a -> a -> Bool) -> [a] -> Maybe Bool 
isOrdered mark (x:y:_) = Just (x `mark` y) 
isOrdered _ _  = Nothing 

请注意,我已经包括了当列表中不包含两个元素的情况下,包裹,结果在一个Maybe。这可以通过强制您处理这种情况来防止运行时错误。