Определение новой монады в haskell не вызывает инстанции для Applicative

haskell monads

7099 просмотра

2 ответа

Я пытаюсь определить новую монаду и получаю странную ошибку

newmonad.hs

newtype Wrapped a = Wrap {unwrap :: a}
Экземпляр Monad Завернут где
  (>> =) (Wrap x) f = fx
  возврат х = обтекание х

main = do
  putStrLn "yay"
$ ghc - версия
Система составления Glorious Glasgow Haskell, версия 7.10.1

$ ghc newmonad.hs 
[1 из 1] Компиляция Main (newmonad.hs, newmonad.o)

newmonad.hs: 2: 10:
    Нет экземпляра для (Applicative Wrapped)
      возникающие из суперклассов объявления экземпляра
    В декларации экземпляра для "Monad Wrapped"

Почему мне нужно определить экземпляр Applicative?

Автор: fakedrake Источник Размещён: 12.11.2019 09:52

Ответы (2)


81 плюса

Решение

Это Аппликативное предложение монады (AMP). Теперь, когда вы объявляете что-то как Monad, вы также должны объявлять это как Applicative(и, следовательно, Functor). Математически говоря, каждая монада является аппликативным функтором, так что это имеет смысл.

Вы можете сделать следующее, чтобы удалить ошибку:

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

В зависимости от рассматриваемой монады возможны более эффективные реализации, но это простая отправная точка.

Автор: MathematicalOrchid Размещён: 27.07.2015 12:02

1 плюс

Самый нормализованный и ненавязчивый ответ:

поскольку монада зависит от аппликативного

Класс Applicative m => Monad m где ...

и Applicative зависит от Functor

Класс Functor f => Применимый f где ...

нам нужны определения экземпляров

> instance Functor Wrapped where
>     fmap = liftM

а также

> instance Applicative Wrapped where
>     pure = return
>     (<*>) = ap
Автор: AaronNGray Размещён: 10.07.2018 05:22
Вопросы из категории :
32x32