我试图自学Haskell而且我相当新,所以我想知道是否有人可以帮助我。我试图编写一个反转名称顺序的函数,这样如果我输入,
ghci> fullName "harry" "potter"
我应该得到,
"potter, harry"
我尝试过的事情:
我知道要打印出前两个字符,我需要做
initials :: String -> String -> String
initials firstname lastname = [l] ++ [b] ++ ", " ++ [f] ++ [a]
where (f:a:_) = firstname
(l:b:_) = lastname
这将得到:
ghci> initials "harry" "potter"
"po, ha"
它有效,但问题是当你不知道名字中有多少个字符时它需要工作。我应该可以输入任何随机名称,无论多长时间,它应该能够颠倒顺序。我觉得它非常明显,但我没有得到它。
答案 0 :(得分:8)
String
是[Char]
的类型别名,因此您可以使用++
fullname :: String -> String -> String
fullname first last = last ++ ", " ++ first
答案 1 :(得分:4)
首先,作为提示,您可以将其更具惯用性地写为
initials (f:a:_) (l:b:_) = [l, b] ++ ", " ++ [f, a]
但这就是所谓的部分功能(不要与部分功能应用混淆)。这里我的意思是函数可以是部分函数或总函数。如果函数是total,则为其输入类型的所有可能值定义。例如,没有为输入initials
定义initials "" ""
,因此您将获得模式匹配错误,表明它不是完整的。在数学上,这意味着对于f :: A -> B
,对于a
中的所有A
,b
中有B
,f a = b
。{ / p>
有两种(常见的)方法可以实现这样的功能。您可以使用更多模式匹配,如
initials [] [] = ", "
initials [a] [] = ", " ++ [a]
initials [] [b] = [b] ++ ", "
initials (f:a:_) (l:b:_) = [l, b] ++ ", " ++ [f, a]
或者您可以使用内置函数take
:
initials firstname lastname = take 2 lastname ++ ", " ++ take 2 firstname
第二个更清洁,避免担心匹配每个模式,但有时模式匹配绝对是可行的方法。
对于使用任意长度的名称,由于String
与[Char]
相同,因此您可以像使用++
那样使用++ ", " ++
:
fullname firstname lastname = lastname ++ ", " ++ firstname