Program Tip

Haskell에서 빈 목록을 확인하기 위해 == [] 대신 null 함수를 사용하는 이유는 무엇입니까?

programtip 2020. 12. 14. 20:46
반응형

Haskell에서 빈 목록을 확인하기 위해 == [] 대신 null 함수를 사용하는 이유는 무엇입니까?


나는 위대한 선을위한 하스켈 배우기 의 "시작하기"장을 읽고있다 ! . 그것은 말한다 :

null목록이 비어 있는지 확인합니다. 그렇다면을 반환 True하고 그렇지 않으면을 반환합니다 False. 대신이 함수를 사용하십시오 xs == [](라는 목록이있는 경우 xs).

나는 ghci에서 시도했다.

xs = []      -- and then,

xs == []
null xs

둘 다 True.

차이점이 무엇인지 궁금합니다.

null대신 함수를 사용해야 == []하며 그 이유는 무엇입니까?


당신은 사용해야합니다 null. 대부분의 경우 문제가되지는 않지만 가끔은 비교할 수없는 목록이 비어 있는지 확인하고 싶을 수 있기 때문에 어쨌든 들어가는 것이 좋은 습관입니다. 다음은이 차이점을 보여주는 짧고 선명한 예입니다.

> null [id]
False
> [id] == []
<interactive>:1:1: error:
    • No instance for (Eq (a0 -> a0)) arising from a use of ‘==’
        (maybe you haven't applied a function to enough arguments?)
    • In the expression: [id] == []
      In an equation for ‘it’: it = [id] == []

차이가 있습니다. 를 사용 x == []하려면 목록의 요소 유형이 유형 Eq클래스 의 구성원이어야합니다 . 실제로 두 목록이 같은지 확인하는 것은 인스턴스 선언으로 정의됩니다.

instance Eq a => Eq [a] where
    []     == []      =  True
    (x:xs) == (y:ys)  =  x == y  &&  xs == ys
    _      == _       =  False

, 예를 들어 s 목록 인 x == []경우 사용할 수 없습니다 .xIO Int

null :: [a] -> Bool반면에 패턴 일치를 사용합니다. 이것은 다음 과 같이 구현됩니다 .

null                    :: [a] -> Bool
null []                 =  True
null (_:_)              =  False

따라서 목록의 요소 유형에 관계없이 항상 유형 검사를 수행합니다.


지금까지 주어진 좋은 답변 외에도 null실제로 유형이 있습니다.

null :: Foldable t => t a -> Bool

LYAH에서 타입 클래스를 사용했는지는 모르겠지만, 목록뿐만 아니라 .NET null을 구현하는 모든 데이터 구조에 사용할 수 있다는 단점이 있습니다 null.

이것은 nulla Map또는 a 를 사용 하는 Set것도 유효하다는 뜻입니다.

> null Map.empty
True
> null (Map.singleton 1)
False
> null Set.empty
True
> null (Set.singleton 1)
False
> null []
True
> null [1]
False

이처럼 일반적이어야하는 함수를 작성하는 것이 특히 일반적이라고 생각하지 않지만, 더 일반적인 코드를 작성하는 것이 기본적으로 나쁘지는 않습니다.

참고 사항

대부분의 경우 null목록 (또는 기타 데이터 구조)에서 조건부 동작을 수행 하는 것과 같은 함수를 사용하고 싶을 것 입니다. 입력이 특정 데이터 구조라는 것을 이미 알고 있다면 빈 케이스에 대한 패턴 일치 만하는 것이 더 우아합니다.

비교

myMap :: (a -> b) -> [a] -> [b]
myMap f xs
  | null xs = []
myMap f (x:xs) = f x : myMap f xs

...에

myMap' :: (a -> b) -> [a] -> [b]
myMap' f [] = []
myMap' f (x:xs) = f x : myMap' f xs

일반적으로 합리적이라면 패턴 매칭을 선호해야합니다.


또한 모든 빈 목록을 필터링하는 간단한 함수는 실패합니다.

withoutEmpty = filter (== [])

그리고 그것은 :

withoutEmpty = filter null

그것을주의해라:

withoutEmpty ls = filter (==[]) ls

잘 작동하지만 중요한 점은 다른 것과 같은 경우에 실패 할 수 있다는 것입니다.

Also look at @cole answer, it complements all the answers here, the typeclass Foldable has the null function there to be implemented:

To see more info of Foldable here

참고URL : https://stackoverflow.com/questions/57029258/why-use-null-function-instead-of-to-check-for-empty-list-in-haskell

반응형