Как проверить, меньше ли строка, чем другой в Haskell?

Оказывается, это то, что сработало для меня:

Admin’ or ‘1=1

Я не совсем уверен, почему это также работает, но это работает:

Admin’ or ‘
6
задан nbro 12 September 2017 в 15:04
поделиться

6 ответов

Я бы использовал что-то вроде следующего:

smaller :: String -> String -> Bool
smaller s1 s2 | len1 /= len2         = (len1 < len2)
              | otherwise            = (s1 < s2)
              where (len1, len2) = (length s1, length s2)

Вот примерный прогон в объятиях:

Main> smaller "b" "aa"
True
Main> smaller "aa" "b"
False
Main> smaller "this" "that"
False
Main> smaller "that" "this"
True
9
ответ дан 8 December 2019 в 03:28
поделиться

Одноходовое решение:

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
7
ответ дан 8 December 2019 в 03:28
поделиться

Попробуйте:

compare s1 s2

(возвращает LT, EQ или GT).

5
ответ дан 8 December 2019 в 03:28
поделиться

String является экземпляром Ord , и поэтому вы можете использовать все эти методы для лексикографического сравнения строк. Как сказал Эндрю, это по существу сравнивает , но также и операторы сравнения, (<) и др.

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

Это работает для всех типов , реализующих Ord (и на самом деле это просто грубая оболочка для (<) ), включая String .

2
ответ дан 8 December 2019 в 03:28
поделиться

Обычное сравнение строк работает только для лексикографического упорядочения, а не для длины строк.

Поэтому вам нужно написать собственную функцию, чтобы также проверять длину:

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

Но если вы этого не сделаете вполне понимаю, я предлагаю вам придерживаться первого определения; -)

2
ответ дан 8 December 2019 в 03:28
поделиться

Более короткая версия версии 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)
4
ответ дан 8 December 2019 в 03:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: