在 Haskell 中反转订单
Reversing an Order in 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"
它可以工作,但问题是当您不知道名称中有多少个字符时它需要工作。无论多长时间,我都应该能够输入任何随机名称,并且它应该能够颠倒顺序。我觉得这是非常明显的事情,但我不明白。
String
是 [Char]
的类型别名,因此您可以将 ++
与
一起使用
fullname :: String -> String -> String
fullname first last = last ++ ", " ++ first
首先,作为提示,您可以将您所拥有的更地道地写成
initials (f:a:_) (l:b:_) = [l, b] ++ ", " ++ [f, a]
但这就是所谓的偏函数(不要与偏函数应用混淆)。在这里我的意思是一个函数可以是部分的或全部的。如果一个函数是总函数,那么它是为它的输入类型的所有可能值定义的。 initials
没有为输入 initials "" ""
定义,例如,所以你会得到一个模式匹配错误,表明它不是总的。更数学地说,这意味着对于 f :: A -> B
,对于 A
中的所有 a
,B
中有一个 b
使得 f a = b
.
有两种(常见的)方法可以实现这样的功能。您可以使用更多模式匹配,例如
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
我正在努力自学 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"
它可以工作,但问题是当您不知道名称中有多少个字符时它需要工作。无论多长时间,我都应该能够输入任何随机名称,并且它应该能够颠倒顺序。我觉得这是非常明显的事情,但我不明白。
String
是 [Char]
的类型别名,因此您可以将 ++
与
fullname :: String -> String -> String
fullname first last = last ++ ", " ++ first
首先,作为提示,您可以将您所拥有的更地道地写成
initials (f:a:_) (l:b:_) = [l, b] ++ ", " ++ [f, a]
但这就是所谓的偏函数(不要与偏函数应用混淆)。在这里我的意思是一个函数可以是部分的或全部的。如果一个函数是总函数,那么它是为它的输入类型的所有可能值定义的。 initials
没有为输入 initials "" ""
定义,例如,所以你会得到一个模式匹配错误,表明它不是总的。更数学地说,这意味着对于 f :: A -> B
,对于 A
中的所有 a
,B
中有一个 b
使得 f a = b
.
有两种(常见的)方法可以实现这样的功能。您可以使用更多模式匹配,例如
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