我正在尝试编写一个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语句中。我已经越过了每一行,他们似乎对我来说是正确的。
非常感谢有关此行为发生原因以及如何解决此问题的任何建议。
答案 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