我是一个初学者在Haskell。我面临的错误是在标题。下面是我的Haskell代码。
member atm lizt = if null lizt
then False
else if atm == head lizt then True else member(atm (tail lizt))
main = print(member 1 [2, 1])
错误消息
GHCi, version 8.10.6: https://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/runner/member/.ghci
[1 of 1] Compiling Main ( Main.hs, interpreted )
Main.hs:1:1: error:
• Couldn't match type ‘[t0 -> t] -> Bool’ with ‘Bool’
Expected type: t -> Bool
Actual type: (t0 -> t) -> [t0 -> t] -> Bool
• Relevant bindings include
member :: t -> Bool (bound at Main.hs:1:1)
|
1 | member atm lizt = if null lizt
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
Main.hs:5:14: error:
• Couldn't match expected type ‘[a1] -> a0’ with actual type ‘Bool’
• The function ‘member’ is applied to two arguments,
but its type ‘t1 -> Bool’ has only one
In the first argument of ‘print’, namely ‘(member 1 [2, 1])’
In the expression: print (member 1 [2, 1])
|
5 | main = print(member 1 [2, 1])
| ^^^^^^^^^^^^^^^
Failed, no modules loaded.
<interactive>:1:1: error:
• Variable not in scope: main
• Perhaps you meant ‘min’ (imported from Prelude)
^C Leaving GHCi.
repl process died unexpectedly:
GHCi, version 8.10.6: https://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/runner/member/.ghci
如果给定的整数(在我的例子中是atm)出现在给定的列表中,我试图打印true,否则打印false。在我添加递归调用之前,代码正在工作(只是检查列表的第一个元素)。
2条答案
按热度按时间hsgswve41#
我认为您对函数的调用有误解。
member
是一个两个参数的函数。它可以像member atm (tail lizt)
一样调用。当你像member(atm (tail lizt))
一样调用它时,atm (tail lizt)
会告诉它把atm
作为tail lizt
上的一个函数来调用。但是atm
不应该是一个函数。你需要用两个参数atm
和tail lizt
来调用member
。你得到的编译器错误并不是很严重。编译器知道有什么地方出错了,但它并不确切地知道是什么。这类令人困惑的错误在Haskell中经常发生。处理它们的最好方法是注意到你有一个类型错误,然后开始添加类型签名。如果你在代码中添加你想要的
member
的类型签名:这样编译器就能更好地了解您要执行的操作,并给出更有帮助的答案:
如果您只是在开始时添加类型签名,这也会有所帮助,因为它们有助于将您的代码应该做的事情传达给其他人。
vfhzx4xs2#
除了已经提供的answer之外,我想指出的是,模式匹配和条件保护可以显著地清理代码。
head
的使用将lizt
标识为列表,因此我们可以对其进行模式匹配,而不是使用null
、head
或tail
;然后使用条件保护来确定第一个元素是否等于我们要查找的值。当然,这基本上只是
elem
。除了上述情况,至少要格式化代码以减少水平滚动。