无法使用head和++匹配类型

时间:2016-10-16 17:13:16

标签: function haskell types

我是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语句后面有两行代码。非常感谢任何帮助,谢谢。

1 个答案:

答案 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 cChar++要求双方都是[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没有从其他功能调用业务。