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 |
This would all be much easier with pattern matching. For example:
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
Hello Dimitri, Rene On Sat, Jul 18, 2015 at 6:47 PM, Dimitri DeFigueiredo <[hidden email]> wrote: Thanks Karl! _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners |
In reply to this post by Dimitri DeFigueiredo
On Sat, Jul 18, 2015, at 09:47 AM, Dimitri DeFigueiredo wrote:
> 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. Yes, that's exactly right - it would be another way to end up in cabal hell. There is another option, though: you could put the executables in separate packages. -Karl _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners |
Free forum by Nabble | Edit this page |