Explicitly determining which pure function to use - haskell

One of the examples from Learn You a Haskell is:
pure (+) <*> Just 3 <*> Just 5
He states:
So at first, we have pure (+), which is Just (+)
I'm assuming that Haskell is using type inference on the <*> function to determine that the pure function on the LHS will be the one from the Maybe instance of the Applicative type class (based on the fact we're using Just 5 on the RHS, and Just is a Maybe).
However, is there ever a case where you have a value you'd like to turn into an Applicative Functor using the pure method, but you aren't going to use it right away via the <*> function and thus Haskell can't determine which pure function to use? If so, how would you be explicit state which pure function to use?
Or, is it the case that Haskell won't try to determine which pure function until the result of the pure function is used in some context (such as when you feed it to a <*> function at some point)

You would give it a type annotation. If you were defining it as a variable, you would use a top-level type signature:
foo :: Maybe (Integer -> Integer -> Integer)
foo = pure (+)
(This also works in let and where clauses.)
Or if you were using it in an expression, you'd write (pure (+) :: Maybe (Integer -> Integer -> Integer)).
You can also get the relevant pure function without having to apply it to an argument. Since we have:
pure :: (Applicative f) => a -> f a
...we can say (pure :: a -> Maybe a) to get a pure of the desired type. But (pure :: a -> Maybe a) (+) is more confusing than pure (+) :: Maybe (Integer -> Integer -> Integer), so the latter is probably more useful in general.
The last sentence of your question is correct, however: you can assign pure (+) to a variable without a type signature, and use it later at a specific concrete type (such as Maybe (Integer -> Integer -> Integer)) without having to use any type annotations at all. (There's a slight restriction: if you define it as a top-level variable without any type signature, then you can only use it as one specific type, not two in different places, due to the monomorphism restriction... but you probably don't need to worry about that.)

Related

What's the meaning of `fmap` over set of predicates in Haskell?

My student assignment I'm doing for Haskell programming includes a task I'm a little bit puzzled to solve. The things are given so: an instance of Functor class to be created just for a set-based new type. There is a declaration of that:
newtype Set x = Set { contains :: (x -> Bool) }
It's a case for me to understand what means if fmap serves to be applied to something like a set of predicates. When doing about previous tasks, I've already defined fmap rather with functions like (+3) (to alter integers), (toUpper) (to strings) etc. It's first time I'm dealing with anything beyond normal types (various numerics, String, Char). There is my humble attempt to start:
instance Functor Set where
fmap f (Set x) = if (contains x) == True then Set (f x) else Set x
Surely, it's a nonsense code, but I suppose some True/False need to be evaluated before fmap apllication goes well. But, first of all, would you please explain the matter of set of predicates to elaborate more sensible approach?
With this definition, it is actually impossible to define a Functor instance for Set. The reason for this is that your Set a type contains a in a negative position... that is, a is an argument to a function, not a value. When that happens, the type constructor can be a contravariant functor (type class Contravariant from the contravariant package), but it cannot be a covariant functor (the Functor type class).
Here's are definitions of those classes:
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Contravariant f where
contramap :: (a -> b) -> f b -> f a
See the difference? In a contravariant functor, the direction of the function you pass in is flipped when it's lifted to operate on the functor type.
In the end, this should make sense. Your notion of a "set" is a test that tells you whether something qualifies or not. This is a perfectly good mathematical definition of a set, but it gives you different computational powers than the standard one. For example, you cannot get at the elements of your predicate-based sets; only wait to be given a potential element. If you have a Set Integer, and a function f :: String -> Integer, then you can test Strings by first converting them to Integers and testing those, so you can get from Set Integer to Set String. But having a g :: Integer -> String doesn't let you test Strings!
If this is an assignment, then either you've misunderstood the assignment, you've done some earlier step differently than expected (e.g., if you defined Set yourself in an earlier part, maybe you need to change the definition), or perhaps your instructor is hoping you'll struggle with this and understand why Functor cannot be defined.

Why does the type of a function change when it comes out of a monad in GHCi [duplicate]

This question already has an answer here:
Why does `peek` with a polymorphic Ptr return GHC.Prim.Any when used with a bind?
(1 answer)
Closed 6 years ago.
Something changes about the type of a function when it comes out of a monad.
In GHCI:
> :t map
map :: (a -> b) -> [a] -> [b]
> a <- return map
> :t a
a :: (GHC.Prim.Any -> GHC.Prim.Any)
-> [GHC.Prim.Any] -> [GHC.Prim.Any]
This change makes it hard to store the function in a higher rank type.
What is happening here and can I make it not happen?
(Also doesn't this violate one of the monad laws?)
First of all, there is no point in doing anything like a <- return map - its the same as let a = map, which works just fine. That said, I don't think that is your question...
Checking out the documentation of GHC.Prim.Any which gives us a big hint as to the role of Any.
It's also used to instantiate un-constrained type variables after type
checking. For example, length has type
length :: forall a. [a] -> Int
and the list datacon for the empty list has type
[] :: forall a. [a]
In order to compose these two terms as length [] a
type application is required, but there is no constraint on the
choice. In this situation GHC uses Any
(In terms of type application syntax, that looks like length #Any ([] #Any *))
The problem is that when GHCi sees x <- return map it tries to desugar it to return map >>= \x -> ... but the ... part is whatever you enter next into GHCi. Normally it would figure out what the type variables of map are going to be instantiated to (or whether they even should be instantiated to anything) based the ..., but since it has nothing there.
Another key point that #sepp2k points out is that x can't be given a polymorphic type because (>>=) expects (on its RHS) a rank-1 function, and that means its argument can't be polymorphic. (Loosening this condition pushes you straight into RankNTypes at which point you lose the ability to infer types reliably.)
Therefore, needing x to be monomorphic and having no information to help it instantiate the type variables that prevent x from being monomorphic, it defaults to using Any. That means that instead of (a -> b) -> [a] -> [b] you get (Any -> Any) -> [Any] -> [Any].

What if function application was a typeclass?

Suppose Haskell's function application (the "space" operator) were in a typeclass instead of baked into the language. I imagine it would look something like
class Apply f where
($) :: f a r -> a -> r
instance Apply (->) where
($) = builtinFnApply#
And f a would desugar to f $ a. The idea is that this would let you define other types that act like functions, ie
instance Apply LinearMap where
($) = matrixVectorMult
and so on.
Does this make type inference undecidable? My instinct says that it does, but my understanding of type inference stops at plain Hindley-Milner. As a follow up, if it is undecidable, can it be made decidable by outlawing certain pathological instances?
If you can envision this as a syntactic sugar on top of Haskell (replacing the "space operator" with yours), I can't see why this should make type inference any worse than it already is.
I can however see that code might be more ambiguous with this change, e.g.
class C a where get :: a
instance C (Int -> Int) where get = id
instance C Linearmap where get = ...
test = get (5 :: Int) -- actually being (get $ (5 :: Int))
Above get could be picked from both instances, while such ambiguity does not arise in plain Haskell.

When are type signatures necessary in Haskell?

Many introductory texts will tell you that in Haskell type signatures are "almost always" optional. Can anybody quantify the "almost" part?
As far as I can tell, the only time you need an explicit signature is to disambiguate type classes. (The canonical example being read . show.) Are there other cases I haven't thought of, or is this it?
(I'm aware that if you go beyond Haskell 2010 there are plenty for exceptions. For example, GHC will never infer rank-N types. But rank-N types are a language extension, not part of the official standard [yet].)
Polymorphic recursion needs type annotations, in general.
f :: (a -> a) -> (a -> b) -> Int -> a -> b
f f1 g n x =
if n == (0 :: Int)
then g x
else f f1 (\z h -> g (h z)) (n-1) x f1
(Credit: Patrick Cousot)
Note how the recursive call looks badly typed (!): it calls itself with five arguments, despite f having only four! Then remember that b can be instantiated with c -> d, which causes an extra argument to appear.
The above contrived example computes
f f1 g n x = g (f1 (f1 (f1 ... (f1 x))))
where f1 is applied n times. Of course, there is a much simpler way to write an equivalent program.
Monomorphism restriction
If you have MonomorphismRestriction enabled, then sometimes you will need to add a type signature to get the most general type:
{-# LANGUAGE MonomorphismRestriction #-}
-- myPrint :: Show a => a -> IO ()
myPrint = print
main = do
myPrint ()
myPrint "hello"
This will fail because myPrint is monomorphic. You would need to uncomment the type signature to make it work, or disable MonomorphismRestriction.
Phantom constraints
When you put a polymorphic value with a constraint into a tuple, the tuple itself becomes polymorphic and has the same constraint:
myValue :: Read a => a
myValue = read "0"
myTuple :: Read a => (a, String)
myTuple = (myValue, "hello")
We know that the constraint affects the first part of the tuple but does not affect the second part. The type system doesn't know that, unfortunately, and will complain if you try to do this:
myString = snd myTuple
Even though intuitively one would expect myString to be just a String, the type checker needs to specialize the type variable a and figure out whether the constraint is actually satisfied. In order to make this expression work, one would need to annotate the type of either snd or myTuple:
myString = snd (myTuple :: ((), String))
In Haskell, as I'm sure you know, types are inferred. In other words, the compiler works out what type you want.
However, in Haskell, there are also polymorphic typeclasses, with functions that act in different ways depending on the return type. Here's an example of the Monad class, though I haven't defined everything:
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
fail :: String -> m a
We're given a lot of functions with just type signatures. Our job is to make instance declarations for different types that can be treated as Monads, like Maybe t or [t].
Have a look at this code - it won't work in the way we might expect:
return 7
That's a function from the Monad class, but because there's more than one Monad, we have to specify what return value/type we want, or it automatically becomes an IO Monad. So:
return 7 :: Maybe Int
-- Will return...
Just 7
return 6 :: [Int]
-- Will return...
[6]
This is because [t] and Maybe have both been defined in the Monad type class.
Here's another example, this time from the random typeclass. This code throws an error:
random (mkStdGen 100)
Because random returns something in the Random class, we'll have to define what type we want to return, with a StdGen object tupelo with whatever value we want:
random (mkStdGen 100) :: (Int, StdGen)
-- Returns...
(-3650871090684229393,693699796 2103410263)
random (mkStdGen 100) :: (Bool, StdGen)
-- Returns...
(True,4041414 40692)
This can all be found at learn you a Haskell online, though you'll have to do some long reading. This, I'm pretty much 100% certain, it the only time when types are necessary.

Signature of IO in Haskell (is this class or data?)

The question is not what IO does, but how is it defined, its signature. Specifically, is this data or class, is "a" its type parameter then? I didn't find it anywhere. Also, I don't understand the syntactic meaning of this:
f :: IO a
You asked whether IO a is a data type: it is. And you asked whether the a is its type parameter: it is. You said you couldn't find its definition. Let me show you how to find it:
localhost:~ gareth.rowlands$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Prelude> :i IO
newtype IO a
= GHC.Types.IO (GHC.Prim.State# GHC.Prim.RealWorld
-> (# GHC.Prim.State# GHC.Prim.RealWorld, a #))
-- Defined in `GHC.Types'
instance Monad IO -- Defined in `GHC.Base'
instance Functor IO -- Defined in `GHC.Base'
Prelude>
In ghci, :i or :info tells you about a type. It shows the type declaration and where it's defined. You can see that IO is a Monad and a Functor too.
This technique is more useful on normal Haskell types - as others have noted, IO is magic in Haskell. In a typical Haskell type, the type signature is very revealing but the important thing to know about IO is not its type declaration, rather that IO actions actually perform IO. They do this in a pretty conventional way, typically by calling the underlying C or OS routine. For example, Haskell's putChar action might call C's putchar function.
IO is a polymorphic type (which happens to be an instance of Monad, irrelevant here).
Consider the humble list. If we were to write our own list of Ints, we might do this:
data IntList = Nil | Cons { listHead :: Int, listRest :: IntList }
If you then abstract over what element type it is, you get this:
data List a = Nil | Cons { listHead :: a, listRest :: List a }
As you can see, the return value of listRest is List a. List is a polymorphic type of kind * -> *, which is to say that it takes one type argument to create a concrete type.
In a similar way, IO is a polymorphic type with kind * -> *, which again means it takes one type argument. If you were to define it yourself, it might look like this:
data IO a = IO (RealWorld -> (a, RealWorld))
(definition courtesy of this answer)
The amount of magic in IO is grossly overestimated: it has some support from compiler and runtime system, but much less than newbies usually expect.
Here is the source file where it is defined:
http://www.haskell.org/ghc/docs/latest/html/libraries/ghc-prim-0.3.0.0/src/GHC-Types.html
newtype IO a
= IO (State# RealWorld -> (# State# RealWorld, a #))
It is just an optimized version of state monad. If we remove optimization annotations we will see:
data IO a = IO (Realworld -> (Realworld, a))
So basically IO a is a data structure storing a function that takes old real world and returns new real world with io operation performed and a.
Some compiler tricks are necessary mostly to remove Realworld dummy value efficiently.
IO type is an abstract newtype - constructors are not exported, so you cannot bypass library functions, work with it directly and perform nasty things: duplicate RealWorld, create RealWorld out of nothing or escape the monad (write a function of IO a -> a type).
Since IO can be applied to objects of any type a, as it is a polymorphic monad, a is not specified.
If you have some object with type a, then it can be 'wrappered' as an object of type IO a, which you can think of as being an action that gives an object of type a. For example, getChar is of type IO Char, and so when it is called, it has the side effect of (From the program's perspective) generating a character, which comes from stdin.
As another example, putChar has type Char -> IO (), meaning that it takes a char, and then performs some action that gives no output (in the context of the program, though it will print the char given to stdout).
Edit: More explanation of monads:
A monad can be thought of as a 'wrapper type' M, and has two associated functions:
return and >>=.
Given a type a, it is possible to create objects of type M a (IO a in the case of the IO monad), using the return function.
return, therefore, has type a -> M a. Moreover, return attempts not to change the element that it is passed -- if you call return x, you will get a wrappered version of x that contains all of the information of x (Theoretically, at least. This doesn't happen with, for example, the empty monad.)
For example, return "x" will yield an M Char. This is how getChar works -- it yields an IO Char using a return statement, which is then pulled out of its wrapper with <-.
>>=, read as 'bind', is more complicated. It has type M a -> (a -> M b) -> M b, and its role is to take a 'wrappered' object, and a function from the underlying type of that object to another 'wrappered' object, and apply that function to the underlying variable in the first input.
For example, (return 5) >>= (return . (+ 3)) will yield an M Int, which will be the same M Int that would be given by return 8. In this way, any function that can be applied outside of a monad can also be applied inside of it.
To do this, one could take an arbitrary function f :: a -> b, and give the new function g :: M a -> M b as follows:
g x = x >>= (return . f)
Now, for something to be a monad, these operations must also have certain relations -- their definitions as above aren't quite enough.
First: (return x) >>= f must be equivalent to f x. That is, it must be equivalent to perform an operation on x whether it is 'wrapped' in the monad or not.
Second: x >>= return must be equivalent to m. That is, if an object is unwrapped by bind, and then rewrapped by return, it must return to its same state, unchanged.
Third, and finally (x >>= f) >>= g must be equivalent to x >>= (\y -> (f y >>= g) ). That is, function binding is associative (sort of). More accurately, if two functions are bound successively, this must be equivalent to binding the combination thereof.
Now, while this is how monads work, it's not how it's most commonly used, because of the syntactic sugar of do and <-.
Essentially, do begins a long chain of binds, and each <- sort of creates a lambda function that gets bound.
For example,
a = do x <- something
y <- function x
return y
is equivalent to
a = something >>= (\x -> (function x) >>= (\y -> return y))
In both cases, something is bound to x, function x is bound to y, and then y is returned to a in the wrapper of the relevant monad.
Sorry for the wall of text, and I hope it explains something. If there's more you need cleared up about this, or something in this explanation is confusing, just ask.
This is a very good question, if you ask me. I remember being very confused about this too, maybe this will help...
'IO' is a type constructor, 'IO a' is a type, the 'a' (in 'IO a') is an type variable. The letter 'a' carries no significance, the letter 'b' or 't1' could have been used just as well.
If you look at the definition of the IO type constructor you will see that it is a newtype defined as: GHC.Types.IO (GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, a #))
'f :: IO a' is the type of a function called 'f' of apparently no arguments that returns a result of some unconstrained type in the IO monad. 'in the IO monad' means that f can do some IO (i.e. change the 'RealWorld', where 'change' means replace the provided RealWorld with a new one) while computing its result. The result of f is polymorphic (that's a type variable 'a' not a type constant like 'Int'). A polymorphic result means that in your program it's the caller that determines the type of the result, so used in one place f could return an Int, used in another place it could return a String. 'Unconstrained' means that there's no type class restricting what type can be returned and so any type can be returned.
Why is 'f' a function and not a constant since there are no parameters and Haskell is pure? Because the definition of IO means that 'f :: IO a' could have been written 'f :: GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, a #)' and so in fact has a parameter -- the 'state of the real world'.
In the data IO a a have mainly the same meaning as in Maybe a.
But we can't rid of a constructor, like:
fromIO :: IO a -> a
fromIO (IO a) = a
Fortunately we could use this data in Monads, like:
{-# LANGUAGE ScopedTypeVariables #-}
foo = do
(fromIO :: a) <- (dataIO :: IO a)
...

Resources