我是Haskell(和函数式编程)的初学者。我在尝试一段非常简单的代码时遇到了这个问题:
Ciphers.hs:24:25:
Couldn't match expected type ‘Bool’ with actual type ‘[Char]’
In the expression: sChars ++ (head c)
和
Ciphers.hs:24:41:
Couldn't match type ‘Char’ with ‘[Char]’
Expected type: [[Char]]
Actual type: Cipher
这是我试图执行的代码:
--Datatype for a cipher
type Cipher = String
validateCipher :: Cipher -> Bool
validateCipher ciph =
if((length ciph) /= 26)then
False
else if(let savedChars = "" in vCiph ciph savedChars)then
True
else
False
vCiph :: Cipher -> String -> Bool
vCiph c sChars =
if(elem (head c) sChars)then
False
else if(length c == 0)then
True
else
sChars ++ (head c)
vCiph (tail c) sChars
所以它确实是造成问题的最后两行,我无法弄清楚原因。老实说,我甚至不确定为什么预期的类型在第一个中是bool,为什么编译器的列号与Notepad ++不匹配或者是否与我允许在else语句后面有两行代码。非常感谢任何帮助,谢谢。
答案 0 :(得分:3)
首先,有超级容易的"做事的方式。
import Data.List
type Cipher = String
validateCipher :: Cipher -> Bool
validateCipher c = sort c == ['a'..'z']
然后可以解决你想要做的事情:
type Cipher = String
validateCipher :: Cipher -> Bool
validateCipher ciph = length ciph == 26 && vCiph ciph ""
vCiph :: Cipher -> String -> Bool
vCiph "" _ = True
vCiph (c:cs) prev
| elem c prev = False
| otherwise = vCiph cs (c:prev)
我在代码中注意到的一些事情:
代码检查head c
是否在sChars
中,然后检查c
是否为空。但如果c
为空,则为时已晚,因为head c
会引发异常。
代码sChars ++ (head c)
不会修改sChars
。它会创建一个新列表。
代码sChars ++ (head c)
是类型错误,因为head c
是Char
而++
要求双方都是[Char]
。
新版本通过模式匹配完成任务:模式(c:cs)
将参数分为头部和尾部,因此您不必调用head
和{{1}明确地。模式tail
将匹配空字符串,因此您不必测试""
。
以下是一种样式修正,解决了您对length c == 0
成为Cipher
的担忧:
String
使用newtype Cipher = Cipher String
validateCipher :: Cipher -> Bool
validateCipher (Cipher ciph) = length ciph == 26 && vCiph ciph ""
where
vCiph :: String -> String -> Bool
vCiph "" _ = True
vCiph (c:cs) prev
| elem c prev = False
| otherwise = vCiph cs (c:prev)
代替newtype
使type
不再是Cipher
,就类型系统而言。可以把它想象成一个带有字符串的盒子。除了边缘情况之外,几乎与String
相同。
data Cipher = Cipher String
部分vCiph
表明validateCipher
没有从其他功能调用业务。