2014-12-03 3 views
1

전처리 정의를 재정의 할 수 없으므로 newtype을 사용하여 모나드 목록 인스턴스를 재정의하여 래핑 된 목록 유형을 만들려고 시도하고 있습니다. 의 정의 내 기능을 사용하여, 인스턴스에 대한 연산자 = >>을 정의하는 방법을 알고 난 딱하다, 하스켈 초보자로서모나드리스트 인스턴스를 다시 정의하기

newtype MyList a = MyList { unMyList :: [a] } 
    deriving Show 

myReturn :: a -> [a] 
myReturn x = [x] 

myBind :: [a] -> (a -> [b]) -> [b] 
myBind m f = concat $ map f m 

instance Monad MyList where 
    return x = MyList [x] 
    xs >>= f = undefined 

:

지금까지 나는 다음과 같은이 묶다.

myReturn 및 myBind 함수에 일반 유형 변수가 아닌 MyList를 사용해야합니까? >> =를 정의하는 데 필요한 패킹과 언 패킹은 어떻게합니까?

f : a -> [b]가있는 f를 매핑하는 함수 인수에 갇혀 있지만 f :: a -> MyList b가 필요하지만 다음으로 map이 허용하지 않습니다. 논증.

혼란에 사과드립니다. 모든 도움이 감사하겠습니다.

[I가 여기에 비슷한 질문입니다 알고 :. Redefine list monad instance는하지만 난 거기에 대한 답을 따라 갈 수 없어 유감]

+1

이 왜 그런 방법으로 목록을 포장 할 것 ? 'data List t = Empty |를 사용하여 새로운 단독 연결 목록을 만들지 않겠습니까? t : + (List t)'를 선택하고 그런 식으로 다시 정의하십시오 - 확실히 더 실용적인 운동이며 도전하는 것입니까? – AJFarmar

답변

5
당신은 단순히 다음을 다시 포장, 그것에서 작동, 당신의 MyList 형 랩을 해제 할 필요가

최대 :

instance Monad MyList where 
    return x = MyList [x] 
    (MyList xs) >>= f = MyList . concat . map unMyList . map f $ xs 

당신은 (그리고해야) MyList $ concatMap (unMyList . f) xs이를 축소 할 수 있습니다,하지만 난 그것을 설명을위한 확대 떠 났어요. 당신은 MyList에 대한 자신 mapconcat 기능을 정의하여이 정의를 단순화 할 수 있습니다 :

myMap :: (a -> b) -> MyList a -> MyList b 
myMap f (MyList xs) = MyList $ map f xs 

myConcat :: MyList (MyList a) -> MyList a 
myConcat (MyList xs) = MyList $ concat $ map unMyList xs 

myConcatMap :: (a -> MyList b) -> MyList a -> MyList b 
myConcatMap f xs = myConcat $ myMap f xs 

instance Monad MyList where 
    return x = MyList [x] 
    xs >>= f = myConcatMap f xs 

을 그리고 지금은 일반 목록 인스턴스 같습니다

instance Monad [] where 
    return x = [x] 
    xs >>= f = concatMap f xs 
+0

필자는'Functor'를 파생시킨 다음'myMap = fmap'을 제안합니다. –

+0

@SassaNF 또한 추천할만한 것이지만,이 경우에는 모나드 인스턴스에 집중하려고했습니다. 그래도 꽤 사소한 변화 일 것입니다. – bheklilr

+0

예, 동의합니다. 주제의 중요한 중복이 될 수 있습니다. ''>> = f = $ fmap f a''에 합류하십시오. –

관련 문제