Haskell에서 문자열이 다른 것보다 작은 지 확인하는 방법은 무엇입니까?
문제
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)
샘플 실행은 다음과 같습니다.
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를 반환합니다).
더 짧은 버전의 mappend
위의 Tom Lokhorst의 버전 :
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
이것은 효과가 있습니다 모든 유형 구현 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
그러나 당신이 이것을 잘 이해하지 못하면, 나는 당신이 첫 번째 정의를 고수하는 것이 좋습니다 ;-)
제휴하지 않습니다 StackOverflow