2016-10-10 6 views
3

람다 함수의 응용 펑터를 테스트하고 있지만 아래 코드로 작성했습니다. 'myAddition가'랜덤에 '의 총 누적 취할 필요 : 그러나 나는 펑터를 배우고, 내가 아래의 작업을 수행하는 더 나은 방법이 감사람다 식, 비 한정적인 패턴 내의 적용 펑터?

을 그래서 이것은 관련

data Random a = Nill | Random a deriving (Show, Ord, Eq) 

randomOrNot = [Nill, Random 22, Random 101, Nill, Random 44] 

instance Functor Random where 
    fmap f (Nill) = Nill 
    fmap f (Random a) = Random (f a) 

instance Applicative Random where 
    pure a = Random a 
    (<*>) (Random a) = fmap a 

cumulativeTotal :: [Random a] -> Random a 
cumulativeTotal li = foldr (\el acc -> (pure (+) <*> el) <*> acc) (Random 0) li 

main = do 
    print $ cumulativeTotal randomOrNot 

오류 :

오류의 의미를 이해하지만 응용 펑터 람다를 철저하게 만드는 방법을 확신하지 못합니까?

instance Applicative Random where 
    pure a = Random a 
    (Random f) <*> (Random a) = Random (f a) 
    _ <*> _ = Nill 

첫째, 형식 f (a -> b) <*> f a)으로 가져오고 Random (f a)으로 첫 번째 경우에 대한 결과를 정의

+1

는 어떻게해야합니까? –

+1

'Applicative Random' 인스턴스에서'(<*>) Nill' 사례를 처리하지 않습니다. –

+0

랜덤 타입은 위장한 것일 수도 있습니다. – chepner

답변

3

다음은이 문제를 해결할 수있는 하나의 방법입니다. 그런 다음 f (a -> b)f a 조건에 관계없이 결과를 Nill로 설정하여 입력이 Nill 인 사례를 처리합니다. 이렇게하면 Random 생성자의 모든 가능한 값을 처리하고 비 한정적인 패턴 문제를 해결할 수 있습니다.

또는 동일한 결과를 추가과 같이 아래의 경우 분할을 실시 할 가능성이있다 : 당신이 NILL에 적용하는 경우

instance Applicative Random where 
    pure a = Random a 
    (Random f) <*> (Random a) = Random (f a) 
    _ <*> Nill = Nill 
    Nill <*> (Random a) = Nill 

Demo

+0

Nill 값을 건너 뛰거나 무시하려면 어떻게해야합니까? 그렇지 않으면 위의 솔루션에서 Nill 값의 인스턴스가 누적 된 결과가 Nill이됩니다. –

+0

그러면 주어진 출력에 대해 예상되는 출력이 어떻게됩니까? –

+0

[Nill, Random 2, Random 4] = Random 6 (귀하의 솔루션 인 Nill) –