我正在努力教自己Haskell。我试图做的一件事是编写一个替代函数,通过递归列表返回列表的最后一个元素,直到尾部为空集然后返回头部。我有......
mylast [] = []
mylast (x:[]) = x
mylast (x:xs) = mylast xs
...但是当我尝试任何非空列表时出现错误:( 关于我做错了什么的任何建议? TIA。
答案 0 :(得分:31)
问题 - 就像你学习Haskell时的许多其他问题一样 - 是打字的问题。在GHCi中输入以下内容
:t mylast
你会看到类型签名是
mylast :: [[a]] -> [a]
需要列表列表并返回列表。因此,如果您输入字符串列表[“bob”,“fence”,“house”],该函数将在您编写时起作用。
问题是你的基本情况:mylast [] = [],它告诉编译器你想要返回一个列表。您想要返回一个元素,而不是一个列表。但是Haskell中没有空元素(非常多的是设计),所以你需要使用Maybe monad。
mylast :: [a] -> Maybe a
mylast [] = Nothing
mylast (x:[]) = Just x
mylast (x:xs) = mylast xs
Monads是一个有点抽象的话题,但是当你开始时你需要Maybe monad。所有你需要知道的是它是一个类型声明,告诉编译器期望两种可能性:“Nothing”或“Just x”。返回的代码然后可以使用x并运行它,但是如果你不使用“Just”,编译器就会抱怨。
另一种方法是在遇到空列表时抛出错误,如下所示:
mynextlast [] = error "no empty lists allowed"
mynextlast (x:[]) = x
mynextlast (x:xs) = mynextlast xs
但我的怀疑是,可能是要走的路。
答案 1 :(得分:8)
请尝试使用mylast [] = error "Empty list!"
。否则Haskell无法推断出函数的类型。
答案 2 :(得分:6)
EFraim的解决方案应该有效(投票)。但我认为这更像是“像Haskell一样”:
mylast [] = Nothing
mylast (x:[]) = Just x
mylast (x:xs) = mylast xs
免责声明:我实际上没有试过这个。我可能犯了语法错误。
答案 3 :(得分:1)
myLast' [] = error "no empty lists allowed"
myLast' [a] = a
myLast' xs = xs !! (length xs - 1)
答案 4 :(得分:0)
感谢大家的答案。我试过......
mylast :: [a] -> Maybe a
mylast [] = Nothing
mylast (x:[]) = Just x
mylast (x:xs) = mylast xs
我得到了......
Main> mylast3 [2,4,66,5,4,33]
Just 33 :: Maybe Integer
有没有让它在答案中不打印“正好”?
[编辑:JörgWMittag](评论发布代码很糟糕......)
以下是整个代码在上下文中的显示方式:
mylast [] = Nothing
mylast [x] = Just x
mylast (x:xs) = mylast xs
mylook (Just a) = do print a
mylook Nothing = do error "Nothing to see here, move along!"
mylook $ mylast [2,4,66,5,4,33]
答案 5 :(得分:0)
mylast [x] = x
mylast (x:xs) = mylast xs
递归呼叫解决方案