What make the difference between `:t` and let expression in GHCi - haskell

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"

Related

Weird behaviour of pure from Applicative in GHCi

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!

Polymorphic functions in Record Types Haskell

i've stumbled upon a behaviour I can't explain in Haskell. I'm trying to store a polymorphic function in a Record Type, which I want to use in a ReaderT Monad. When I get my function with asks, the compiler doesn't recognize it as polymorphic and seems to fix the type on the first occurance of the function. I created a minimal example of this in ghci:
{-# LANGUAGE Rank2Types #-}
data Test = Test {f :: (forall a. a -> a)}
runReaderT (asks f
>>= \f -> (liftIO . putStrLn $ show (f 2 :: Int))
>> (liftIO . putStrLn $ show (f "hello"))
) (Test id)
When trying to run this, I get:
Couldn't match expected type ‘Int’ with actual type ‘[Char]’
In the first argument of ‘f’, namely ‘"hello"’
In the first argument of ‘show’, namely ‘(f "hello")’
In the second argument of ‘($)’, namely ‘show (f "hello")’
However, following code works:
runReaderT (ask
>>= \(Test f) -> (liftIO . putStrLn $ show (f 2 :: Int))
>> (liftIO . putStrLn $ show (f "hello"))
) (Test id)
So is it something special with asks? I'm grateful for any advice on this.
Last time I checked, GHC could not infer higher rank types. Thus, when you have
\f -> ... f x .... f y
the f can never be polymorphic.
There are only two places where the type of some variable is so obvious that type inference recognizes the higher rank type: in patterns that declare higher rank fields and in the LHS of annotated functions.
It also should work to give the type explicitly, like in
\(f :: forall a.a -> a) -> .... f x ... f y

Learning Haskell - How to simplify expressions?

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.

ghci special case for Applicative?

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).

Why is GHCi typing this statement oddly?

In answering a question on stackoverflow, I noticed that GHCi (interactive) is assigning a too-restrictive type in a let statement. Namely, given the code,
import Control.Arrow
f = maximum &&& id >>> fst &&& (\(m,l) -> length $ filter (==m) l)
(as on my answer to https://stackoverflow.com/questions/6281813/maximum-of-list-and-count-of-repeat-maximum-number/6283594#6283594), if one inserts a "let" before f and enters this in ghci, it gives the following type information
Prelude Control.Arrow> :t f
f :: [()] -> ((), Int)
whereas just asking for the type of the expression gives the correct result, namely Ord a => [a] -> (a, Int). I'm using ghc 7.0.3.
See the extended defaulting rules used in GHCi for an explanation of where the () is coming from.
As for why the defaulting occurs in this case, compare the following:
> let f x = maximum &&& id >>> fst &&& (\(m,l) -> length $ filter (==m) l) $ x
> :t f
f :: (Ord a) => [a] -> (a, Int)
I assume this has something to do with bindings being monomorphic, but I'm not certain of the details.

Resources