Haskell错误 - 无法将预期类型'Char'与实际类型'[Char]匹配

时间:2016-12-06 17:05:09

标签: string haskell char

我正在尝试编写一个Haskell函数,该函数将获取一个人的全名并仅返回姓氏;例如,getName "Hans Christian Anderson"应返回"Anderson"。功能如下:

getname :: String -> String
getname fullName = do
  let nameList = splitOn " " fullName    -- split the full name into individual names
  let reversedName = reverse nameList    -- reverse the full name
  let lastName = reversedName !! 0       -- get the first name from the reversed list
  return lastName

但每当我尝试编译时,我都会收到以下错误:

Couldn't match expected type ‘Char’ with actual type ‘[Char]’
In the first argument of ‘return’, namely ‘lastName’
In a stmt of a 'do' block: return lastName

我不确定我是否完全理解这个错误。据我了解Haskell(我对它很新),结构[Char]String相同,这正是我所寻找的。我只是不明白为什么它期望这个Char类型看起来像是在String中出现在return语句中。我已经越过了每一行,他们似乎对我来说是正确的。

非常感谢有关此行为发生原因以及如何解决此问题的任何建议。

2 个答案:

答案 0 :(得分:5)

此处不要使用do表示法。由于函数的返回值为[Char],因此return的参数应为Char值(因为return :: a -> [a])。

你这里没有做任何需要do符号的事情;只需使用常规函数调用。

getname fullName = (reverse (splitOn " " fullName)) !! 0

答案 1 :(得分:2)

您的代码意外地在列表monad中工作,就像它用于描述非确定性计算一样。你不需要那个monad,也不需要任何其他monad。因此,请避免使用do。如果您愿意,仍然可以使用let .. in ..

getname :: String -> String
getname fullName =
  let nameList = splitOn " " fullName    -- split the full name into individual names
      reversedName = reverse nameList    -- reverse the full name
      lastName = reversedName !! 0       -- get the first name from the reversed list
  in lastName

或者,使用last

getname :: String -> String
getname fullName = last (splitOn " " fullName)

请注意last是部分的:只要输入字符串中没有名称,它就会使程序崩溃。更安全的方法可能是:

getname :: String -> Maybe String
getname fullName = case splitOn " " fullName of
   [] -> Nothing
   xs -> Just (last xs)

甚至:

getname :: String -> Maybe String
getname fullName = safeLast (splitOn " " fullName)

-- This should be already there in the library, IMO
safeLast :: [a] -> Maybe a
safeLast []     = Nothing
safeLast [x]    = Just x
safeLast (_:xs) = safeLast xs