在Haskell中,你如何使用' head'没有创建单独的功能?

时间:2015-03-25 20:40:19

标签: haskell head

我对使用Haskell非常陌生,而且我不确定'head'是如何工作的。根据我的理解,它返回列表中的第一个元素。我一直在尝试使用它,但我一直在收到错误。我通过创建一个找到头部的单独函数添加了一个解决方法,但是看起来它应该是不必要的。

我不明白为什么在这里调用findHead:

single x = length (snd(x)) == 1

toList board
    | board == [] = []
    | otherwise = filter single board

findHead board = head (toList board)

不等于在这里调用toList:

single x = length (snd(x)) == 1

toList board
    | board == [] = []
    | otherwise =  head (filter single board)

在我看来,两者应该是相同的,但只有第一个运行。他们为什么不被解释为相同?你能解释一下吗?在上面的代码中,'board'是一个元组列表,每个元组都是形式(x,[a,b,...])。

我在一些简单的事情中使用'head',如:

union xs ys 
  | xs == [] = ys
  | ys == [] = xs
  | otherwise = union (tail xs)  (add (head xs) ys)

似乎按照我的预期工作。

2 个答案:

答案 0 :(得分:8)

head 部分。特别是,head []没有正常返回(抛出异常)。这在Haskell中很难处理,这就是人们经常建议你避免部分功能的原因。

那我们该怎么做?我们必须在类型中反映失败

safeHead :: [a] -> Maybe a
safeHead []     = Nothing
safeHead (a:as) = Just a

可以为tail

制作类似的功能
safeTail :: [a] -> Maybe [a]
safeTail []     = Nothing
safeTail (a:as) = Just as

答案 1 :(得分:1)

我认为您需要退后一步,了解模式匹配,递归和单链接列表的工作原理。正如各种人所提到的那样,你写的代码不会很好用。

这里举例说明我将如何编写你问题中的各种函数:

single :: (a, [b]) -> Bool    
single (_, [_]) = True
single _ = False

toList :: [(a, [b])] -> [(a, [b])]
toList board = filter single board

findHead :: [(a, [b])] -> Maybe (a, [b])
findHead [] = Nothing
findHead board = head (toList board)

-- This one actually does the same thing as the built-in `++` operator,
-- but for the sake of illustration, I'll implement it.
union :: [a] -> [a] -> [a]
union [] ys = ys
union (x:xs) ys = x : union xs ys