An elegant way to return the longer of two lines

I am trying to write a function that returns the longer of two lines. So far this is what I have:

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

This works, but I'm wondering if there is a more elegant way to write this. Note: two arguments cannot be in the list. They must be separate arguments for currying.

Thoughts?

+6
source share
4 answers

So far, all answers except for Tejing have completely passed both arguments. This path goes only to the end of the shorter one.

 longest ab = l' ab where l' _ [] = a l' [] _ = b l' (_:ar) (_:br) = l' ar br 
+9
source

You can use existing Haskell objects in Data.Ord and Data.Function and get a single-line file as follows:

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

code:

 import Data.Ord import Data.Function import Data.List maxString' xy = maximumBy (compare `on` length) [x, y] *Main> maxString' "ab" "c" "ab" 

- EDIT -

As @DavidYoung noted,

 compare `on` length 

can also be written in shorter form: comparing length

+8
source

Played with this a bit. I wanted it to be one liner, as well as O(min(n,m)) complexity. (i.e. works even with infinite lists)

 maxList :: [a] -> [a] -> [a] maxList ss' = if s == zipWith const ss' then s' else s 
+8
source

This is pretty much the most concise way to write it. However, the version below will be completed even if one list is infinite (O (min (a, b)) instead of 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 ab = case compareLengths ab of GT -> a _ -> b 

Also, there is no real reason to limit your function to strings only if that makes sense for arbitrary lists.

+6
source

Source: https://habr.com/ru/post/988814/


All Articles