Week 4 Lecture 2
hs
1import Control.Monad (ap, liftM)2import Data.IORef (IORef)3import System.Posix (otherExecuteMode)45data Test = Test6 { a :: Int7 , b :: Int8 , c :: Int9 }10 deriving (Show)1112data Free f a = Pure a | Free (f (Free f a))1314instance (Functor f) => Functor (Free f) where15 fmap = liftM1617-- fmap f m = m >>= pure . f1819instance (Functor f) => Applicative (Free f) where20 pure = Pure21 (<*>) = ap2223instance (Functor f) => Monad (Free f) where24 (Pure a) >>= f = f a25 (Free cont1) >>= f = Free $ (>>= f) <$> cont12627data StateOps s c = GetState (s -> c) | PutState s c deriving (Functor)2829type FreeState s = Free (StateOps s)3031-- ╭----- Technically `x` can only ever be `Free f a`,32-- ↓ but using "forall" makes certain guarantees that we desire33interpret :: (Monad m, Functor f) => (forall x. f x -> m x) -> Free f a -> m a34interpret _transform (Pure a) = pure a35interpret transform (Free cont) = transform cont >>= interpret transform3637-- @Doboz, where does the original state go? isn't Put just put some value in?38-- We may need some of the originals, no? That's what the s does, isnt' it?39-- For the _s (Free StatePut s' m)40-- then you don't need _s, because it gets overwritten, no? not just appended? no, that's Writer :catthink:, But how does StatePut know of the original s? Or you reduced the computation until StatePut has s built in? Why would you need the original s in StatePut?41-- So another Get in m can get values from state. How does that relate to Put? It's continuation passing style, so Put itself only contains what needs to happen after the current action.4243-- Fibonacci S3 database when?4445-- Kotlin mentioned letsgoooo4647-- @Doboz, qq: can we later generate haskell source code from these free constructors? Like macro definitions at rust...48-- But you already have haskell source code? I mean like extracting the data constructors and compile it to the monad you want to use. Like a framework. So you'd get equivalent code, but ✨faster✨? yes. I guess it's not impossible. You could also just use a typeclass instead of a free monad lmfao49-- Always the typeclasses, but in case some random weirdos do that, can I fix it purely on the syntax level?..50-- I guess there's nothing stopping you. You can actually do it right in haskell through template haskell. from what I've seen, it's actually more powerful than Rust's macros. it's pretty cool51-- hmmm, can this be the goal of the usage of free here?52-- Haskell frameworks53-- no5455-- Space