In ghci:
λ> :t (pure 1)
(pure 1) :: (Applicative f, Num a) => f a
λ> show (pure 1)
<interactive>:1:1:
No instance for (Show (f0 a0))
arising from a use of `show'
Possible fix: add an instance declaration for (Show (f0 a0))
In the expression: show (pure 1)
In an equation for `it': it = show (pure 1)
λ> pure 1
1
Does this mean that ghci execute Applicative and displays the result, just like IO?
Note that pure () and pure (+1) don't print anything.
You get the same behaviour if you use return instead of pure. To find out what to do, ghci must choose a type for the given expression. ghci's defaulting rules are such that absent other constraints, it chooses IO for an Applicative or Monad instance. Thus it interprets pure 1 as an expression of type IO Integer. Expressions of type IO a entered at the prompt are executed and their results are printed, if 1. a has a Show instance and 2. a is not (). Thus entering pure 1 at the prompt results in
v <- return (1 :: Integer)
print v
return v
being executed (and the magic variable it bound to the returned v). For pure (), the special case applies since () is considered uninteresting, thus only return () is executed and it bound to (), for pure (+1), a function is returned, there's no Show instance for functions in scope, so nothing is printed. However,
Prelude Control.Applicative> :m +Text.Show.Functions
Prelude Control.Applicative Text.Show.Functions> pure (+1)
<function>
it :: Integer -> Integer
Prelude Control.Applicative Text.Show.Functions> it 3
4
it :: Integer
with a Show instance for functions in scope, it gets printed (not that it's informative), and the function can then be used (the latter is independent of a Show instance being in scope, of course).
Related
I am reading the excellent article Understanding map and apply by Scott Wlaschin and running some Haskell code to understand the concepts (Functor, Applicative, ...). I stumbled upon a behaviour I do not understand.
Why evaluating pure add1 prints nothing ? What is the value of the evaluated expression ? Why pure add1 "abc" gives me back the function add1 ?
I understand that pure lifts a value into the elevated world (so called in the article). Since I do not provide a concrete lifted value somewhere or enough type information, the type constraint is general and stays Applicative f. Thus I understand the type of pure add1. But the rest of what's happening here eludes me.
$ stack ghci
GHCi, version 8.8.2
λ: add1 :: Int -> Int ; add1 x = x + 1
λ: :t add1
add1 :: Int -> Int
λ: add1 100
101
λ: :t pure
pure :: Applicative f => a -> f a
λ: pure add1
λ: :t pure add1
pure add1 :: Applicative f => f (Int -> Int)
λ: pure add1 "abc"
<interactive>:8:1: error:
• No instance for (Show (Int -> Int)) arising from a use of ‘print’
(maybe you haven't applied a function to enough arguments?)
• In a stmt of an interactive GHCi command: print it
λ: :t pure add1 "abc"
pure add1 "abc" :: Int -> Int
λ: pure add1 "abc" 100
101
EDIT
I think the two comments by #chi and the answer by #sarah answers the question because it shows the applicative chosen by GHCi to evaluate the expression and that explains the observed behaviour.
Since you are applying the expression pure add1 to the value "abc", the Applicative instance gets picked to be the one for (->) String. In that instance, pure = const, so your final expression is const add1 "abc" which is add1, which has no Show instance!
Reading Function application with $ in Learn You Haskell book I found example of applying $ to list of functions.
map ($ 3) [(4+), (10*), (^2), sqrt]
I wanted try similar thing and reduce example to applying to one function
fmap ($ 3) (4+)
But I am getting errors which I don't understand
• Non type-variable argument in the constraint: Num (a -> b)
(Use FlexibleContexts to permit this)
• When checking the inferred type
it :: forall a b. (Num (a -> b), Num a) => (a -> b) -> b
Could you help me understand why it works in the first case but it doesn't in the second? How can I achieve desired effect?
Thank you
You need map in the first example because you have a whole container full of functions, and each of them you want to apply to the number. In that example, you could indeed also replace map with fmap, which does work on any container (on any functor).
Prelude> fmap ($ 3) [(4+), (10*), (^2), sqrt] -- list functor
[7.0,30.0,9.0,1.7320508075688772]
Prelude> fmap ($ 3) (Just (4+)) -- `Maybe` functor
Just 7
Prelude> fmap ($ 3) (do y<-readLn; return (y+)) -- `IO` functor
> 100
103
However, (4+) by itself is not a function wrapped in any functor, it's just a function by itself. So, you don't really need any fmap:
Prelude> ($ 3) (4+)
7
Of course you could simplify that even further to 4+3...
If for some reason you do need to use fmap regardless†, you'd need it to operate in the identity functor:
Prelude> :m +Data.Functor.Identity
Prelude Data.Functor.Identity> fmap ($ 3) (Identity (4+))
Identity 7
The identity functor is a very boring container that just always contains exactly one element.
†That's not unrealistic BTW: in Haskell we like to keep code as generic as possible. You may have a function that is able to work with arbitrary functors (more typically, arbitrary monads, which are special functors) but may want to use it in the trivial context of just one element contained. Or, you may want to stack different monad functionalities as monad transformers; then you'll generally start with Identity as the “vanilla monad”.
I would say the main issue is that your (4 +) is not wrapped correctly inside a functor. If you inspect the type of fmap you'll get:
Prelude> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
In your first example, all the functions were wrapped in a list. Here if you change your (4 +) into [ (4 +) ], it will work.
As for the explanation about functor, you'll probably find more documentation online (or in the comment section :D Thanks for the feedback)
fmap applies a function to values found in some functorial value. In fmap ($ 3) [(4+), (10*), (^2), sqrt], the list is the functorial value, and the function ($ 3) is applied to its elements. As for fmap ($ 3) (4+), leftaroundabout correctly points out that:
However, (4+) by itself is not a function wrapped in any functor, it's just a function by itself.
In this case, there is a complementary way to look at it. (4+) is a functorial value; however, the functor isn't the one you need. Functions are functors, and, for the purposes of fmap, the values "found in them" are the results of the function:
GHCi> :set -XTypeApplications
GHCi> :t fmap #((->) _)
fmap #((->) _) :: (a -> b) -> (w -> a) -> w -> b
fmap for functions applies a function to the results of another function, which amounts to function composition. So this...
GHCi> fmap (4*) (2+) 1
12
... is the same as:
GHCi> ((4*) . (2+)) 1
12
In your case, we have:
GHCi> :t (4+)
(4+) :: Num a => a -> a
So fmap f (4+) will apply f to the Num a => a result of (4+). The type of ($ 3), though, is:
GHCi> :t ($ 3)
($ 3) :: Num a => (a -> b) -> b
And so fmap ($ 3) will expect a functorial value with functions to be possibly found in it:
GHCi> :t fmap ($ 3)
fmap ($ 3) :: (Num a, Functor f) => f (a -> b) -> f b
Putting it all together, we get:
GHCi> :t fmap ($ 3) (4+)
fmap ($ 3) (4+) :: (Num (a -> b), Num a) => (a -> b) -> b
The type error this will lead to has to do with the Num (a -> b) constraint. If there are functions to be found in (4+), then 4 itself must be a function. As 4 is a numeric literal, its type must be also an instance of Num. However, there is no Num instance for functions. Trying fmap ($ 3) (4+) leads to an error which mentions Num (a -> b). That should suggest something is off:
GHCi> fmap ($ 3) (4+)
<interactive>:33:1: error:
* Non type-variable argument in the constraint: Num (a -> b)
(Use FlexibleContexts to permit this)
* When checking the inferred type
it :: forall a b. (Num (a -> b), Num a) => (a -> b) -> b
The "Non-type variable argument" complaint, though, is a bit of a distraction, induced by numeric literals being polymorphic. We can get a more straightforward error either by enabling FlexibleContexts and then trying to use fmap ($ 3) (4+) (which will lead to Num a => a being specialised to Integer thanks to the defaulting rules)...
GHCi> :set -XFlexibleContexts
GHCi> fmap ($ 3) (4+) (2*)
<interactive>:39:1: error:
* No instance for (Num (Integer -> Integer))
arising from a use of `it'
(maybe you haven't applied a function to enough arguments?)
* In the first argument of `print', namely `it'
In a stmt of an interactive GHCi command: print it
... or by specialising the numeric type through a type annotation:
GHCi> fmap ($ 3) ((4 :: Integer)+)
<interactive>:42:13: error:
* Couldn't match type `Integer' with `Integer -> b'
Expected type: Integer -> Integer -> b
Actual type: Integer -> Integer
* In the second argument of `fmap', namely `((4 :: Integer) +)'
In the expression: fmap ($ 3) ((4 :: Integer) +)
In an equation for `it': it = fmap ($ 3) ((4 :: Integer) +)
* Relevant bindings include
it :: Integer -> b (bound at <interactive>:42:1)
Is there any way to take the pain out of expression simplification?
For example, given this expression:
(+) <$> a <*> b $ 1
I would love to see a tool that would explain what it means. It's quite laborious for beginners (finding correct instance function definition in sources, checking operator precedence) to simplify expressions with all steps involved:
fmap (+) a <*> b $ 1
See definition in Data.Functor
(.) (+) a <*> b $ 1
See fmap in Control.Monad.Instances for instance Functor ((->) r)
and so on.
EDIT: To clarify, I'm looking for a way to rewrite expression using actual function definitions so that newcomer could understand the outcome of this expression. How to tell that (<$>) = fmap here? I don't know how to find a particular instance definition (source) using hoogle and other tools.
EDIT: Changed incorrect original expression to match following reductions.
I find that the easy way is to use typed holes available in GHCi 7.8:
> (*10) <$> _a $ 1
Found hole ‘_a’ with type: s0 -> b
Where: ‘s0’ is an ambiguous type variable
‘b’ is a rigid type variable bound by
the inferred type of it :: b at <interactive>:4:1
Relevant bindings include it :: b (bound at <interactive>:4:1)
In the second argument of ‘(<$>)’, namely ‘_a’
In the expression: (* 10) <$> _a
In the expression: (* 10) <$> _a $ 1
So this tells me that a :: s0 -> b. Next is to figure out the order of operators:
> :i (<$>)
(<$>) :: Functor f => (a -> b) -> f a -> f b
infixl 4 <$>
> :i ($)
($) :: (a -> b) -> a -> b
infixr 0 $
So this says that $ is highly right-associative, and given it's type we see that it's first argument must be a function, so a must be a function (double confirmation). This means that (*10) <$> a $ 1 is the same as ((*10) <$> a) $ 1, so we'll focus on (*10) <$> a first.
> :t ((*10) <$>)
((*10) <$>) :: (Num a, Functor f) => f a -> f a
> :t (<$> _a)
Found hole ‘_a’ with type: f a
Where: ‘a’ is a rigid type variable bound by
the inferred type of it :: (a -> b) -> f b at Top level
‘f’ is a rigid type variable bound by
the inferred type of it :: (a -> b) -> f b at Top level
In the second argument of ‘(<$>)’, namely ‘_a’
In the expression: (<$> _a)
So we need a to be a functor. What are available instances?
> :i Functor
class Functor (f :: * -> *) where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
-- Defined in ‘GHC.Base’
instance Functor Maybe -- Defined in ‘Data.Maybe’
instance Functor (Either a) -- Defined in ‘Data.Either’
instance Functor ZipList -- Defined in ‘Control.Applicative’
instance Monad m => Functor (WrappedMonad m)
-- Defined in ‘Control.Applicative’
instance Control.Arrow.Arrow a => Functor (WrappedArrow a b)
-- Defined in ‘Control.Applicative’
instance Functor (Const m) -- Defined in ‘Control.Applicative’
instance Functor [] -- Defined in ‘GHC.Base’
instance Functor IO -- Defined in ‘GHC.Base’
instance Functor ((->) r) -- Defined in ‘GHC.Base’
instance Functor ((,) a) -- Defined in ‘GHC.Base’
So (->) r happens to be one, which is awesome because we know a has to be a function. From the Num constraint, we can determine that r must be the same as Num a => a. This means that (*10) <$> a :: Num a => a -> a. From that we then apply 1 to it, and we'd get (*10) <$> a $ 1 :: Num a, where a is some unknown function.
All this is discoverable using GHCi using :t and :i, along with typed holes. Sure, there's a fair number of steps involved, but it never fails when you're trying to break down a complex expression, just look at the types of different sub-expressions.
GHCi was wonderfully and correctly suggested, and I suggest it too.
I also want to suggest Hoogle, because with the instant search enabled (at the top sidebar at the right there's a button for it), you can search for functions very rapidly, it can provide much, much more information than GHCi, and the best part is that you don't have to mention modules to search in them1. This is in contrast to GHCi where you have to import first:
ghci> :t pure
<interactive>:1:1: Not in scope: ‘pure’
ghci> :m +Control.Applicative
ghci> :t pure
pure :: Applicative f => a -> f a
The Hoogle link above is just one (from the Haskell.org site). Hoogle is a program which you can also install on your machine (cabal install hoogle) and execute queries from the command-line (hoogle your-query).
Sidenote: you'd have to run hoogle data to gather the information first. It requires wget/curl, so if you're on Windows you'd probably need to get this in your path first (or a curl for Windows, of course). On Linux it's almost always built-in (if you don't have it on Linux, just apt-get it). I never use Hoogle from the command-line by the way, it's simply not as accessible, but it can still be very helpful because some text-editors and their plugins can take advantage of it.
Alternatively you can use FPComplete's Hoogle which is sometimes more satisfying (because in my experience it has been aware of more 3rd party libraries. I only use it in those "Hoogling sessions").
There is also Hayoo! by the way.
1 In Hoogle you probably >95% of the time won't have to do this but +Module to import a module if for some reason it's not being searched for (which is the case sometimes for 3rd party libraries).
You can also filter away modules by -Module.
For instance: destroyTheWorld +World.Destroyer -World.Destroyer.Mercy to find destroyTheWorld and make sure you're not looking at the merciful way to do it (This comes very handy with modules with the same function names for different versions, like the ones in Data.ByteString & Data.ByteString.Lazy, Data.Vector & Data.Vector.Mutable, etc.).
Oh and one more awesome advantage of Hoogle is that not only it shows you the function's signature, it can also take you to the module's Haddock pages, so you also gain documentation + in those pages, when available, you can click on "Source" at the right of every function to see how it's being implemented for even more information.
This is outside the scope of the question, but Hoogle is also used to query for function signatures which is just.. mindblowingly helpful. If I want a function that takes an index number and a list and gives me the element in that index, and I wonder if it's already built in, I can search for it within seconds.
I know that the function takes a number and a list, and gives me an element of the list so the function signature must look something along these lines: Int -> [a] -> a (or generically: Num a => a -> [b] -> b), and both instances show up that there really is a function for that ((!!) and genericIndex).
Where GHCi has the upperhand is that you can toy with the expressions, explore them, etc. A lot of times when dealing with abstract functions that means a lot.
Being able to :l(oad) is very very helpful as-well.
If you're just looking for function signatures, you can combine both Hoogle and GHCi.
In GHCi you can type :! cmd, and GHCi will execute cmd in the command-line, and print the results. That means you can Hoogle inside GHCi too, e.g. :! hoogle void.
Start ghci, :cd to the base directory of the source you're reading, :load the module you're interested in, and use the :i command to get the info:
ghci> :i <$>
(<$>) :: Functor f => (a -> b) -> f a -> f b
-- Defined in `Data.Functor'
infixl 4 <$>
ghci> :i $
($) :: (a -> b) -> a -> b -- Defined in `GHC.Base'
infixr 0 $
ghci> :i .
(.) :: (b -> c) -> (a -> b) -> a -> c -- Defined in `GHC.Base'
infixr 9 .
That tells you the type, where it's defined, the associativity (infixl or infixr) and the precedence (the number; higher is tighter). So (*10) <$> a $ 1 is read as ((*10) <$> a) $ 1.
When you :load a module, all of the names that are in scope inside that module will be in scope inside ghci. The one place where this can get annoying is if you have an error in the code, then you can't :i anything inside it. In these cases, you can comment lines out, use undefined, and probably also use typed holes as behlkir suggests (haven't played with those too much yet).
While you're at it, try the :? command in ghci.
Why does the following doesn't print anything:
λ> fmap print (pure 2)
Whereas something like this works:
λ> fmap id (pure 2)
2
Follow the types:
fmap print (pure 2) :: Applicative f => f (IO ())
fmap id (pure 2) :: (Num b, Applicative f) => f b
Lets replace f with IO:
fmap print (pure 2) :: IO (IO ()) -- #1
fmap id (pure 2) :: (Num b) => IO b -- #2
Now you can clearly see that #2 is an action with a numeric result, whereas #1 is an action with another action as a result.
Also, GHCi has the following rules about interactive evaluation:
2.4. Interactive evaluation at the prompt
When you type an expression at the prompt, GHCi immediately evaluates and prints the result:
2.4.1. I/O actions at the prompt
GHCi does more than simple expression evaluation at the prompt. If you type something of type IO a for some a, then GHCi executes it as an IO-computation.
Furthermore, GHCi will print the result of the I/O action if (and only if):
The result type is an instance of Show.
The result type is not ().
Since IO a is not an instance of Show, it won't print the result of the IO action.
Your expression return a computation (no perform it).
You want
fmap print (pure 2) >>= id
with that, we get your computation and run it inside monad.
Look your types
fmap print (pure 2) :: Applicative f => f (IO ())
Note
fmap print (pure 2) >>= id -- #1
is very different (but same "visual" result) than
fmap id (pure 2) -- #2
with #1 we take a computation and run it inside monad printing a number
with #2 we take a number and get value through fmap returning a number
(looking types again
fmap id (pure 2) :: (Num b, Applicative f) => f b
I want to make a toy function that produces a Maybe a and then lift show to make it a Maybe String, but the outcome was weird for me:
λ> :t liftM show . Just
liftM show . Just :: Show a1 => a1 -> Maybe String
λ> liftM show . Just $ 10
Just "10"
λ> let f = liftM show . Just
λ> f 10
<interactive>:9:3:
No instance for (Num ()) arising from the literal `10'
Possible fix: add an instance declaration for (Num ())
In the first argument of `f', namely `10'
In the expression: f 10
In an equation for `it': it = f 10
λ> :t f
f :: () -> Maybe String
λ> let g = liftM show . Just :: (Show a) => a -> Maybe String
λ> :t g
g :: () -> Maybe String
λ> let h = liftM show . Just :: Int -> Maybe String
λ> :t h
h :: Int -> Maybe String
I guess it has something to do with type inference, but I really don't know what happened:
where did that mysterious () come from?
why GHCi didn't complain about ambiguousness?
Dum-duuum!
Next victim of the dreaded monomorphism restriction.
What happens is this: for a definition that looks like a "constant variable" (in the sense that other languages might also use, i.e. not of function type), like f = ..., it is assumed that you wish it to actually behave like a constant (CAF, to be precise). That means, it must not be polymorphic, since with parametric polymorphism there's basically an extra implicit argument to the function (the information which type a1 should be).
To achieve this actual-const-ness, ghci defaults this type variable to whatever specific type it deems least inappropriate. Here, the only constraint is Show; the simplest type fulfilling that is ().
The "correct" way of getting around this is to turn off the monomorphism restriction:
Prelude> :set -XNoMonomorphismRestriction
Prelude> :m +Control.Monad
Prelude Control.Monad> let f = liftM show . Just
Prelude Control.Monad> f 10
Just "10"
Alternatively, you can, like in an actual source file you always should, give proper signatures to identifiers in ghci:
Prelude Control.Monad> let g :: Show a => a -> Maybe String; g = liftM show . Just
Prelude Control.Monad> g 10
Just "10"
Doing that only on the RHS of the = doesn't work, since the monomorphism restriction kicks in only after that is resolved and defaults away the variables (unless, as in h, there are no variables in the first place because you gave a monomorphic signature to the RHS).
Still another thing you can do, simply give the function an explicit argument, then the monomorphism restriction doesn't apply at all. I.e., write it non–point-free:
Prelude Control.Monad> let i a = liftM show $ Just a
Prelude Control.Monad> i 10
Just "10"