Last active
April 15, 2020 07:30
-
-
Save fusion5/cb1d098751a0d1cafce19c6194757bf1 to your computer and use it in GitHub Desktop.
I want a function (doc) in a type class (Documentable) that works in several monads (M1, M2)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Test.hs:48:5: error: | |
• Ambiguous type variable ‘a0’ arising from a use of ‘doc’ | |
prevents the constraint ‘(Documentable (M2 a0))’ from being solved. | |
Probable fix: use a type annotation to specify what ‘a0’ should be. | |
These potential instance exist: | |
instance Documentable (M2 ()) -- Defined at Test.hs:31:10 | |
• In a stmt of a 'do' block: | |
doc "Hello, this is a comment in monad M2" | |
In the expression: | |
do doc "Hello, this is a comment in monad M2" | |
m1_in_m2 $ do doc "Hello, this is a comment in monad M1" | |
In an equation for ‘foo’: | |
foo | |
= do doc "Hello, this is a comment in monad M2" | |
m1_in_m2 $ do doc "Hello, this is a comment in monad M1" | |
| | |
48 | doc "Hello, this is a comment in monad M2" | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# Language TypeSynonymInstances #-} | |
{-# Language FlexibleInstances #-} | |
{-# Language FlexibleContexts #-} | |
{-# LANGUAGE GeneralizedNewtypeDeriving #-} | |
module Main where | |
import Control.Monad.Except | |
import Control.Monad.Trans.State | |
import Data.Sequence as S | |
data M1State = M1State | |
{ docs :: S.Seq String -- Sequence of strings | |
} deriving (Eq, Show) | |
type M1 a = StateT M1State (Except String) a | |
newtype M2 a = M2 { runM2 :: M1 a } | |
deriving (Monad) | |
instance Functor M2 where | |
fmap = liftM | |
instance Applicative M2 where | |
pure = return | |
(<*>) = ap | |
class Documentable a where | |
doc :: String -> a | |
instance Documentable (M2 ()) where | |
doc txt = do | |
M2 $ doc txt | |
instance Documentable (M1 ()) where | |
doc txt = do | |
modify (\s -> s { docs = docs s |> txt }) | |
initialM1 = M1State { docs = S.empty } | |
runM1 = runExcept . flip execStateT initialM1 | |
m1_in_m2 :: M1 a -> M2 a | |
m1_in_m2 = M2 | |
foo :: M2 () | |
foo = do | |
doc "Hello, this is a comment in monad M2" | |
m1_in_m2 $ do | |
doc "Hello, this is a comment in monad M1" | |
main = do | |
putStrLn "Hello World" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment