优雅的方式返回两个字符串的较长时间

时间:2015-06-09 23:23:31

标签: haskell

我试图编写一个返回两个字符串中较长字符的函数。到目前为止,这就是我所拥有的:

maxString :: String -> String -> String
maxString a b
    | (length a) > (length b) = a
    | otherwise = b

这很有效,但我想知道是否有更优雅的方式来写这个。注意:这两个参数不能在列表中。它们必须是单独的参数以允许currying。

思想?

4 个答案:

答案 0 :(得分:9)

到目前为止,除了特经之外的所有答案都完全遍及这两个论点。这个只穿越较短的那个。

longest a b = l' a b where
  l' _ [] = a
  l' [] _ = b
  l' (_:ar) (_:br) = l' ar br

答案 1 :(得分:8)

您可以在Data.OrdData.Function中使用现有的Haskell工具,并按如下方式获取单行:

maxString' x y = maximumBy (compare `on` length) [x, y]

代码:

import Data.Ord
import Data.Function
import Data.List

maxString' x y = maximumBy (compare `on` length) [x, y]

*Main> maxString' "ab" "c"
"ab"

- 编辑 -

@DavidYoung指出,

compare `on` length
上面的

也可以用较短的格式书写:comparing length

答案 2 :(得分:8)

稍微玩了一下这个。我希望它是一个单行且具有复杂性O(min(n,m))。 (即使用无限列表工作)

maxList :: [a] -> [a] -> [a]
maxList s s' = if s == zipWith const s s' then s' else s

答案 3 :(得分:6)

这几乎是最简洁的写作方式。但是,即使一个列表是无限的(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

此外,没有任何理由将你的函数限制为只对字符串使用时才对任意列表有意义。