我有两个字符串作为Haskell函数的参数。
如果s1
比s2
短或者它们长度相同且s1
按字典顺序小于s2
,那么s1
就比s2
小。
如何在Haskell中实现这个功能?
我会使用以下类似的内容:
smaller :: String -> String -> Bool
smaller s1 s2 | len1 /= len2 = (len1 < len2)
| otherwise = (s1 < s2)
where (len1, len2) = (length s1, length s2)
以下是在Hugs中的样例运行:
Main> smaller "b" "aa" 真 Main> smaller "aa" "b" 假 Main> smaller "this" "that" 假 Main> smaller "that" "this" 真
一次性解决方案:
lengthcompare :: Ord a => [a] -> [a] -> Ordering
lengthcompare = lc EQ
where
lc lx [] [] = lx
lc _ [] _ = LT
lc _ _ [] = GT
lc EQ (v:vs) (w:ws) = lc (compare v w) vs ws
lc lx (_:vs) (_:ws) = lc lx vs ws
smaller :: Ord a => [a] -> [a] -> Bool
smaller s1 s2 = lengthcompare s1 s2 == LT
试试这个:
compare s1 s2
import Data.Monoid (mappend)
import Data.Ord (comparing)
compareStrings :: String -> String -> Ordering
compareStrings = comparing length `mappend` comparing id
另一种方法是利用元组的排序:
import Data.Ord (comparing)
import Control.Arrow ((&&&))
compareStrings :: String -> String -> Ordering
compareStrings = comparing (length &&& id)
mappend
compare - MartijnString
是 Ord
的一个实例,因此您可以使用所有这些方法来按字典顺序比较字符串。就像 Andrew 所说的那样,这基本上是 compare
,但也包括比较运算符,如 (<)
等。
smaller :: Ord a => a -> a -> Bool
smaller a b = a < b
Ord
的类型(实际上只是一个粗糙的(<)
包装器),包括String
。smaller :: String -> String -> Bool
smaller s1 s2 | length s1 < length s2 = True
| length s1 > length s2 = False
| otherwise = s1 < s2
compareStrings :: String -> String -> Ordering
compareStrings s1 s2 | length s1 < length s2 = LT
| length s1 > length s2 = GT
| otherwise = compare s1 s2
例子:
ghci> compare "ab" "z"
LT
ghci> compareStrings "ab" "z"
GT
Ord
实例:instance Ord a => Ord [a] where
compare = comparing length
`mappend` comparing head `mappend` comparing tail
compare' :: Ord a => [a] -> [a] -> Ordering
呢? - Aleksandar Dimitrov