在Haskell中撤销订单

时间:2015-01-09 04:20:10

标签: haskell

我试图自学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"

它有效,但问题是当你不知道名字中有多少个字符时它需要工作。我应该可以输入任何随机名称,无论多长时间,它应该能够颠倒顺序。我觉得它非常明显,但我没有得到它。

2 个答案:

答案 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中的所有Ab中有Bf 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