IT이야기

Haskell에서 새 모나드를 정의하면 Applicative에 대한 인스턴스가 발생하지 않습니다.

cyworld 2021. 9. 29. 21:43
반응형

Haskell에서 새 모나드를 정의하면 Applicative에 대한 인스턴스가 발생하지 않습니다.


새 모나드를 정의하려고 하는데 이상한 오류가 발생합니다.

newmonad.hs

newtype 래핑 = 래핑 {unwrap :: a}
인스턴스 Monad 래핑된 위치
  (>>=) (x 줄바꿈) f = fx
  리턴 x = 랩 x

메인 = 하다
  putStrLn "예"
$ ghc --버전
Glorious Glasgow Haskell 컴파일 시스템, 버전 7.10.1

$ ghc newmonad.hs 
[1/1] 메인 컴파일( newmonad.hs, newmonad.o )

newmonad.hs:2:10:
    (적용 래핑)에 대한 인스턴스 없음
      인스턴스 선언의 슈퍼클래스에서 발생
    'ÄòMonad Wrapped'에 대한 인스턴스 선언에서

의 인스턴스를 정의해야 하는 이유는 무엇 Applicative입니까?


이것이 AMP(Applicative Monad Proposal)입니다. 이제 무언가를 로 선언할 때마다 (및 따라서 ) Monad로 선언해야 합니다 . 수학적으로 말하면, 모든 모나드 적용 펑터이므로 이것이 의미가 있습니다.ApplicativeFunctor

다음을 수행하여 오류를 제거할 수 있습니다.

instance Functor Wrap where
  fmap f (Wrap x) = Wrap (f x)

instance Applicative Wrap where
  pure = Wrap
  Wrap f <*> Wrap x = Wrap (f x)

https://wiki.haskell.org/Functor-Applicative-Monad_Proposal

편집: 이것이 최근의이라는 것을 더 분명히 지적 해야 할까요? 게시한 코드는 이전에 작동했지만 최신 버전의 GHC에서는 오류가 발생합니다. 획기적인 변화입니다.

편집: 다음 선언은 모든 모나드에서 작동해야 합니다 .

import Control.Applicative -- Otherwise you can't do the Applicative instance.
import Control.Monad (liftM, ap)

instance Functor ??? where
  fmap = liftM

instance Applicative ??? where
  pure  = return
  (<*>) = ap

Depending on the monad in question, there may be more efficient implementations possible, but this is a simple starting point.


The most normalized and unobtrusive answer is :-

as Monad is dependent upon Applicative

class Applicative m => Monad m where ...

and Applicative is dependent upon Functor

class Functor f => Applicative f where ...

we need the instance definitions

> instance Functor Wrapped where
>     fmap = liftM

and

> instance Applicative Wrapped where
>     pure = return
>     (<*>) = ap

ReferenceURL : https://stackoverflow.com/questions/31652475/defining-a-new-monad-in-haskell-raises-no-instance-for-applicative

반응형