# basic Functor, Applicative and Monad instances

13 messages
Open this post in threaded view
|

## basic Functor, Applicative and Monad instances

 Here are complete working snippets with Functor, Applicative and Monad instances. This is my first attempt to write own instances rather than use ready ones. Here we go: module Part.Monad where import Control.Applicative {-# ANN module ("HLint: ignore Use let"::String) #-}  {-    Val' { val = b1 } can also be written as    Val' b1  -} data Val a = Val' {     val::a }  deriving Show data Weather = Cold | Warm deriving Show instance Functor Val where -- (a -> b) -> f a -> f b    fmap ab fa = let  a1 = val fa                      b1 = ab a1                 in Val' { val = b1 } instance Applicative Val where -- a -> f a    pure a =  Val' { val = a } -- f (a -> b) -> f a -> f b    (<*>) fab fa =  let  ab1 = val fab                         a1 = val fa                         b1 = ab1 a1                    in Val' { val = b1 } instance Monad Val where -- a -> m a    return a = Val' { val = a } --  m a -> (a -> m b) -> m b    (>>=) ma amb = let a1 = val ma                  in amb a1 -- pure and return in this example are interchangeable main::Int -> IO() main i = do                         -- do:   Val as monad    v1 <- pure Val' { val = i }      -- pure: applicative    v2 <- return \$ over20 <\$> v1     -- <\$> : functor    print v2    v3 <- return \$ Val' weather <*> v2  -- <*> : applicative    print v3 over20::Int-> Bool over20 i    | i > 20 = True    | otherwise = False weather::Bool-> Weather weather False = Cold weather True = Warm _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Open this post in threaded view
|

## Re: basic Functor, Applicative and Monad instances

 This would all be much easier with pattern matching. For example:instance Functor Val where  fmap f (Val x) = Val (f x)instance Applicative Val where  pure = Val  Val f <*> Val x = Val (f x) _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Open this post in threaded view
|

## Re: basic Functor, Applicative and Monad instances

 Cheers, Rein. This is new for me. I tried to make it work. BTW the monad instance is not used. Commenting it out has no effect on running main. How can I apply Val (not IO) Monad instance in this example? Could you suggest a simple change? _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Open this post in threaded view
|

## Re: basic Functor, Applicative and Monad instances

 v2: Val monad is now necessary: main::Int -> Val Weather main i = do                         -- do:   Val as monad    v1 <- return \$ Val' i       -- pure: applicative    v2 <- return \$ over20 <\$> v1     -- <\$> : functor    v3 <- Val' weather <*> v2  -- <*> : applicative    return v3 _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Open this post in threaded view
|

## Re: basic Functor, Applicative and Monad instances

 based on this snippet and Rein's comment, here is monad file template for intellij Idea to make new monads a quick exercise: module \${PACKAGE_NAME}.\${NAME} where data \${Type} a = \${ctor} {     \${prop}::a } instance Functor \${Type} where -- (a -> b) -> f a -> f b --   fmap f (\${ctor} x) = \${ctor} (f x)    fmap ab fa = let  a1 = \${prop} fa                      b1 = ab a1                 in fa { \${prop} = b1 } instance Applicative \${Type} where -- a -> f a --  pure = \${ctor}    pure a =  \${ctor} { \${prop} = a } -- f (a -> b) -> f a -> f b --   \${ctor} f <*> \${ctor} x = \${ctor} (f x)    (<*>) fab fa =  let  ab1 = \${prop} fab                         a1 = \${prop} fa                         b1 = ab1 a1                    in fa { \${prop} = b1 } instance Monad \${Type} where -- a -> m a    return a = \${ctor} { \${prop} = a } --  m a -> (a -> m b) -> m b    (>>=) ma amb = let a1 = \${prop} ma                  in amb a1 _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Open this post in threaded view
|

## Re: basic Functor, Applicative and Monad instances

 You have the types of the functions commented out in the instances. If you use {-# LANGUAGE InstanceSigs #-} you can write them for real (and be sure that they're accurate) Tom El Jul 17, 2015, a las 3:53, Imants Cekusins <[hidden email]> escribió: > based on this snippet and Rein's comment, here is monad file template > for intellij Idea to make new monads a quick exercise: > > module \${PACKAGE_NAME}.\${NAME} where > > > data \${Type} a = \${ctor} { >    \${prop}::a > } > > > instance Functor \${Type} where > -- (a -> b) -> f a -> f b > --   fmap f (\${ctor} x) = \${ctor} (f x) >   fmap ab fa = let  a1 = \${prop} fa >                     b1 = ab a1 >                in fa { \${prop} = b1 } > > > instance Applicative \${Type} where > -- a -> f a > --  pure = \${ctor} >   pure a =  \${ctor} { \${prop} = a } > > -- f (a -> b) -> f a -> f b > --   \${ctor} f <*> \${ctor} x = \${ctor} (f x) >   (<*>) fab fa =  let  ab1 = \${prop} fab >                        a1 = \${prop} fa >                        b1 = ab1 a1 >                   in fa { \${prop} = b1 } > > > instance Monad \${Type} where > -- a -> m a >   return a = \${ctor} { \${prop} = a } > > --  m a -> (a -> m b) -> m b >   (>>=) ma amb = let a1 = \${prop} ma >                 in amb a1 > _______________________________________________ > Beginners mailing list > [hidden email] > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners_______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Open this post in threaded view
|

## Re: basic Functor, Applicative and Monad instances

 Right, you'll want to say eg fmap :: (a -> b) -> Val a -> Val b Tom El Jul 17, 2015, a las 12:23, Imants Cekusins <[hidden email]> escribió: >> InstanceSigs > > Thank you Tom. > > this sig does not work though: > fmap ::(a -> b) -> f a -> f b _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Open this post in threaded view
|

## Cabal dependencies are per target or global?

 Hello, I'm trying to figure out how cabal understands dependencies. It seems all "build-depends:" sections have to build satisfied for any one target to be built. Is that correct or is there a problem with my setup? I assumed those "build-depends:" sections were "per target", but apparently that not exactly the case. I have a small .cabal file that builds the second target "myPersonalMain" if and only if I comment out the build-dependencies for the first target (i.e. myAgent) here's my test file agent.cabal: ------------------------------------------------ name:                agent version:             0.1.0.0 synopsis:            Just testing author:              Dimitri DeFigueiredo maintainer:          [hidden email] build-type:          Simple cabal-version:       >=1.20 ---------------------------------------------- executable myAgent    main-is:              Main.hs    hs-source-dirs:       ./src    build-depends:      base >=4.6 && <4.7                      , unordered-containers >= 0.2.3.0                      , unix >= 2.6.0.1                      , process >= 1.1.0.2                      , stm >= 2.4.2    default-language:    Haskell2010 ---------------------------------------------- executable myPersonalMain      main-is:            Mpm.hs      hs-source-dirs:     ./src      build-depends:                    base              >=4.6      default-language:   Haskell2010 ---------------------------------------------- if I try to build the second target I get: cabal build MyPersonalMain ./agent.cabal has been changed. Re-configuring with most recently used options. If this fails, please run configure manually. Resolving dependencies... Configuring agent-0.1.0.0... cabal: At least the following dependencies are missing: process >=1.1.0.2, stm >=2.4.2, unix >=2.6.0.1, unordered-containers >=0.2.3.0 could someone shed some light into this behavior? Thanks, Dimitri _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Open this post in threaded view
|

## Re: Cabal dependencies are per target or global?

 I guess my example was incomplete. I can make GHC run. Here's a modified version where I do have the ghc-options line. I can build an executable for the second target (myPersonalMain) by commenting the "build-depends: section" for the first target (agent). My .cabal file with (commented lines) is: ------------------------------------------------ name:                agent version:             0.1.0.0 build-type:          Simple cabal-version:       >=1.20 ------------------------------------------------ executable agent    main-is:             Main.hs    hs-source-dirs: ./src    -- build-depends:      base >=4.6 && <4.7    --                   , unordered-containers >= 0.2.3.0    --                   , unix >= 2.6.0.1    --                   , process >= 1.1.0.2    --                   , stm >= 2.4.2    -- Base language which the package is written in.    default-language:    Haskell2010 ---------------------------------------------- executable myPersonalMain      main-is:            Mpm.hs      hs-source-dirs:     ./src      ghc-options:       -main-is Mpm      build-depends:                  base              >=4.4      default-language:   Haskell2010 ---------------------------------------------- The contents of Mpm.hs are: module Mpm where main = putStrLn "Hi!" But if I remove the comments in the .cabal file above, I get this: Dis-machine:cabal-tests dimitri\$ cabal build myPersonalMain ./agent.cabal has been changed. Re-configuring with most recently used options. If this fails, please run configure manually. Resolving dependencies... Configuring agent-0.1.0.0... cabal: At least the following dependencies are missing: process >=1.1.0.2, stm >=2.4.2, unix >=2.6.0.1, unordered-containers >=0.2.3.0 Is this a bug? Or am I missing something? Cheers, Dimitri On 17/07/15 15:10, Imants Cekusins wrote: > this could shed some light: > > http://stackoverflow.com/questions/14238729/producing-multiple-executables-from-single-project> > answer #2 was marked as answered > > ghc-options:      -O2 -threaded -with-rtsopts=-N -main-is FirstExecutable _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Open this post in threaded view
|

## Re: Cabal dependencies are per target or global?

 On Fri, Jul 17, 2015, at 04:08 PM, Dimitri DeFigueiredo wrote: > Is this a bug? Or am I missing something? The dependencies are not global. You can see this by trying to import a module in Mpm.hs that is in one of the unique dependencies of "agent" - the import fails. [1] However, in order to build, you must first configure. And the "configure" step cannot be done for a single executable - it's done for the whole package. Since package dependencies are checked during the configure step, you have to have all the dependencies in place for all targets. I think this is probably a good thing, because otherwise, you could end up installing some packages that satisfy the dependencies of one target, only to find out that the particular package versions which were chosen make it impossible to satisfy the dependencies of the other target. -Karl 1. https://gist.github.com/ktvoelker/d561889ac4bd56cadc2d_______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Open this post in threaded view
|

## Re: Cabal dependencies are per target or global?

 Thanks Karl! The way cabal is working makes sense now. I don't like it, though. Having a build fail because of changes made to another target is counter-intuitive to me. I don't understand your argument for why the current behavior is a good thing. It seems we would be extending so called "cabal hell" to within targets in a package if we were to change this? I do wish there were other options here. Anyway, thanks again for the explanation! Dimitri Em 17/07/15 19:29, Karl Voelker escreveu: > On Fri, Jul 17, 2015, at 04:08 PM, Dimitri DeFigueiredo wrote: >> Is this a bug? Or am I missing something? > The dependencies are not global. You can see this by trying to import a > module in Mpm.hs that is in one of the unique dependencies of "agent" - > the import fails. [1] > > However, in order to build, you must first configure. And the > "configure" step cannot be done for a single executable - it's done for > the whole package. Since package dependencies are checked during the > configure step, you have to have all the dependencies in place for all > targets. > > I think this is probably a good thing, because otherwise, you could end > up installing some packages that satisfy the dependencies of one target, > only to find out that the particular package versions which were chosen > make it impossible to satisfy the dependencies of the other target. > > -Karl > > 1. https://gist.github.com/ktvoelker/d561889ac4bd56cadc2d> _______________________________________________ > Beginners mailing list > [hidden email] > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners_______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners