2017-12-19 5 views
2

저는 haskell에 상당히 익숙하지만 다행스럽게도 몇 가지 기능 만 구현해야합니다. 나는 다음과 같은 기능하스켈 다음 기능은 무엇을합니까?

next :: Eq a => [a] -> a -> a 
next [email protected](x:_) e = case dropWhile (/= e) l of 
        (_:y:_) -> y 
        _ -> x 
  • [email protected]는 무엇을 하는가에 대한 질문이 있습니까?
  • dropWhile (/= e) l of은 무엇을 의미합니까 특히 /= 운영자
  • of이 상황에서 무엇을 의미합니까?
  • (_:y:_)의 기능은 무엇입니까? 나는 (x:xs)이 당신이 머리 또는 꼬리를 움켜 잡도록 허락 할 것이지만 무엇이 y에 있는지 알 수 있습니까?
  • 화살표는 무엇을 할 것입니까? _ -> x
+7

나는 코스 (?)가 조직되어 있지만, 이것이 첫 번째 사례 중 하나라면, 코스가 너무 많은 개념을 한 번에 소개하기 때문에 코스가 약간 재구성되어야합니다. –

답변

13

좋은 질문입니다!

라고한다는 같은 패턴. 그것은 전체 패턴에 이름을 부여합니다. [email protected](x:_)은 목록을 하나 이상의 요소와 일치시키는 패턴입니다. 목록의 머리를 x으로 명명하고 목록의 꼬리를 버리고 전체 목록의 이름을 지정합니다 (즉, x:_의 값인 l).

/=dropWhile (/= e) l of가 서 무엇을

  • , 특히 /= 연산자는 하스켈은 "동일하지"주문 방법이다. 그것은 예를 들어 자바에서 !=과 같습니다. 중첩 연산자에 괄호 안에 하나의 인수가 주어진 (/= e) 구문은 구역이라고합니다. 그것은 (\x -> x /= e)의 약자입니다. 따라서 dropWhile (/= e) le과 같지 않은 한 l의 요소를 삭제합니다.

    • of이 상황에서 무엇을 의미합니까?

    이것은 표현식 구문 case의 일부입니다.

    case foo of 
        bar -> ... 
        baz -> ... 
        ... 
    
    • (_:y:_)는 무엇입니까 :이 지점에서 scrutinee을 분리? 나는 (x:xs)이 당신이 머리 또는 꼬리를 움켜 잡도록 허락 할 것이지만 무엇이 y에 있는지 알 수 있습니까?

    그건 좀 더 복잡한 패턴입니다.이 경우 두 개 이상의 요소가있는 목록과 일치하고 두 번째 요소의 이름은 y입니다.

    x:xs은 머리를 꼬리에서 분리합니다. x:(y:ys)은 처음 두 요소를 나머지 요소와 구분합니다. (:)은 오른쪽 연관이므로 괄호 ([x:y:ys])를 삭제할 수 있으며 _은 "이 것에 관심이 없습니다"라는 의미입니다.

    • 화살표는 무엇을할까요? _ -> x

    다시 말하지만, 그것은 case 표현 구문의 한 부분입니다. 패턴을 반환 값과 분리합니다. 이 경우 패턴은 포괄적 인 와일드 카드 패턴이며 반환 값은 x입니다.


    은 요약하면 :이 기능은 le을 찾아서 다음과 같은 요소를 반환 할 예정이다. 즉, 그 아이디어를 특별히 훌륭하게 구현 한 것은 아닙니다. 나는 두 가지 특별한 문제를 스파이.

    1. 그것은 예외와 함께 실패 (그리고 프로그램을 충돌!) next의 선언에서 [] 경우에 대한 조항이 없기 때문에 입력 목록이 비어있는 경우 것입니다. next부분 기능입니다.
    2. dropWhile (/= e) l이 두 개 이상의 요소가있는 목록을 반환하지 않으므로 (_:y:_ 패턴이 일치하지 않음) 목록의 첫 번째 요소 인 x을 반환합니다. (이것은 e가 목록에서 빠지거나 마지막 요소 일 경우 발생할 수 있습니다.) 이것은 매우 이상한 일처럼 보입니다.

    나는 아마 lnext 요소가되지 않을 수있는 가능성에 대한 회계로 문제를 해결할 것입니다. el의 마지막 요소 일 수도 있고 l이 아닐 수도 있습니다. 이것은 구현의 버그뿐만 아니라이 함수의 의미에서 기본적인 부분이므로 유형에 대해 설명해야합니다. nextMaybe a의 반환 형식을 제공함으로써

    next :: Eq a => [a] -> a -> Maybe a 
    

    , 나는 아무것도 반환하지 않을 수도 있음을 나타내는거야.

    next l e = case dropWhile (/= e) l of 
           (_:x:_) -> Just x 
           _ -> Nothing 
    

    그래서이 구현은 말한다 : dropWhile (/= e) l 적어도 두 가지 요소의 목록을 반환하는 경우, 두 번째를 반환합니다. (을 사용하여 Maybe에 값을 입력하십시오. 그렇지 않으면 Nothing을 반환하십시오.

    너무 많은 것에 대해 걱정하지 마십시오.하지만 가치가있는 부분에 대해서는 하스켈의 고급 기능 중 하나를 사용하여이 기능을 약간 단축 할 수 있습니다. ViewPatterns 언어 확장은 보조 값에 대한 case 분석을 수행하는 것과 같은 기능을 단순화하도록 설계되었습니다.

    {-# LANGUAGE ViewPatterns #-} 
    next :: Eq a => a -> [a] -> Maybe a -- I've flipped the arguments 
    next e (dropWhile (/= e) -> _:x:_) = Just x 
    next _ _ = Nothing 
    
+0

이 질문은 9 분 전, 3 분 지났음 우리는 awesome 대답을 가지고있다 : –

+0

엄청난 대답, 좋은 폐하. 고맙습니다. –

+0

@GeorgeMorris가 제 편집을보고, 원래 함수에서 몇 가지 버그를 수정했습니다 :) –

관련 문제