我有两个字符串作为Haskell函数的参数。

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"
True
Main> smaller "aa" "b"
False
Main> smaller "this" "that"
False
Main> smaller "that" "this"
True

其他提示

一次性解决方案:

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

(返回LT,EQ或GT)。

Tom Lokhorst上面的mappend版本的缩短版本:

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)

String Ord 的一个实例,因此,您可以使用所有这些方法按字典顺序比较字符串。正如安德鲁所说,这基本上是compare,但也包括比较运营商,(<)等等。

smaller :: Ord a => a -> a -> Bool
smaller a b = a < b

这适用于所有类型实现<=>(实际上只是<=>的粗略包装),包括<=>。

普通字符串比较仅适用于词典排序,而不适用于字符串的长度。

所以你必须编写自己的函数来检查长度:

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

我们上周在大学里玩弄Monoids,我们想出了这个可爱的替代Ord实例:

instance Ord a => Ord [a] where
  compare = comparing length
              `mappend` comparing head `mappend` comparing tail

但如果你不太明白这一点,我建议你坚持第一个定义; - )

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top