我正在尝试编写一个返回两个字符串中较长字符的函数.到目前为止,这就是我所拥有的:
maxString :: String -> String -> String
maxString a b
| (length a) > (length b) = a
| otherwise = b
Run Code Online (Sandbox Code Playgroud)
这有效,但我想知道是否有更优雅的方式来写这个.注意:这两个参数不能在列表中.它们必须是单独的参数以允许currying.
思考?
到目前为止,除了特经之外的所有答案都完全遍及这两个论点.这个只穿越较短的一端.
longest a b = l' a b where
l' _ [] = a
l' [] _ = b
l' (_:ar) (_:br) = l' ar br
Run Code Online (Sandbox Code Playgroud)
您可以使用现有的Haskell工具Data.Ord,Data.Function并获得如下所示的单行:
maxString' x y = maximumBy (compare `on` length) [x, y]
Run Code Online (Sandbox Code Playgroud)
码:
import Data.Ord
import Data.Function
import Data.List
maxString' x y = maximumBy (compare `on` length) [x, y]
*Main> maxString' "ab" "c"
"ab"
Run Code Online (Sandbox Code Playgroud)
- 编辑 -
正如@DavidYoung指出的那样,
compare `on` length
Run Code Online (Sandbox Code Playgroud)
以上也可以用更短的形式写成: comparing length
玩了一下这个.我希望它既可以是单线也可以是复杂的O(min(n,m)).(即使用无限列表工作)
maxList :: [a] -> [a] -> [a]
maxList s s' = if s == zipWith const s s' then s' else s
Run Code Online (Sandbox Code Playgroud)
这几乎是最简洁的写作方式.但是,即使一个列表是无限的(O(min(a,b))而不是O(a + b)),下面的版本也将终止.
compareLengths :: [a] -> [b] -> Ordering
compareLengths [ ] [ ] = EQ
compareLengths (a:as) [ ] = GT
compareLengths [ ] (b:bs) = LT
compareLengths (a:as) (b:bs) = compareLengths as bs
maxList :: [a] -> [a] -> [a]
maxList a b = case compareLengths a b of
GT -> a
_ -> b
Run Code Online (Sandbox Code Playgroud)
此外,没有任何理由将你的函数限制为只对字符串使用时才对任意列表有意义.