Haskell에서 문자열이 다른 것보다 작은 지 확인하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/819620

  •  03-07-2019
  •  | 
  •  

문제

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

그러나 당신이 이것을 잘 이해하지 못하면, 나는 당신이 첫 번째 정의를 고수하는 것이 좋습니다 ;-)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top