learning type of argument in function - haskell

How can I learn type of argument at function in Haskell ? In python, we have type ( ) function.
Ex:
in func;
if type ( a ) == Int
do <something>
But, I don't know how I can manage that wish in Haskell ?

You don't need this since Haskell is statically typed and all types are known at compile time. In case of polymorphic functions like length :: [a] -> Int (Calculate the length of a list of elements of type a), there is no way to find out about the type of the argument, since you specified with the type that any argument type fits.

You have http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Typeable.html
However compared to dynamic languages it is very very rare that you need to use such means, and as beginner you shouldn't even try to use it, as you're almost certainly doing it wrong, even if you are sure that you need it. You should embrace Haskell's battle cry "Follow the type!" and express your thoughts using the type system instead of trying to subvert it.

If you are trying to do type-directed dispatch, then you probably want a typeclass.
data Bar = ...
class Foo a where
foo :: a -> Bar
instance Foo Int where
foo = ...
func :: Foo a => a -> ...
func x ... = ... foo x ...
Notice how the type signature demands that x is an instance of the Foo class. That means we can call foo on x and the type-directed dispatch will be done for us, in a type-safe way. If you write code that tries to call foo on something that is not an instance of Foo, then it will be a type error.
The reason you are not allowed to perform your own type-directed dispatch in Haskell is because that would break some important guarantees given to you by the type system. We would have to say goodbye to our theorems for free.

Related

Haskell RankNTypes - restriction of function domain

I don't understand why it is so, referring to : What is the purpose of Rank2Types? -> #dfeuer explanation:
... Requiring an argument to be polymorphic doesn't just allow it to be used with multiple types; it also restricts what that function can do with its argument(s) and how it can produce its result
...
f :: (forall a . [a] -> a) -> IO ()
... In fact, no function returning an element not in the list it is given will typecheck
In any explanation of rank-N types I haven't see this effect (or benefit) described, much of the time it was the story about letting the callee choose the type etc... that is clear for me and easy to grasp but I don't see by which virtue (only of extending the rank) we can control/restrict the function domain (and co-domain)...
if somebody could give a deeper insigth of the rankN mechanism involved here. thx
Just think about it in terms of polymorphic functions you declare on the top-level. A function with the signature like
foo :: [Int] -> Int
has lots of possible implementations like
foo = sum
foo = length
foo _ = 39
but none of these are legal if the signature were
foo :: [a] -> a
because then you can't give an integer as the result – you must provide a result of whatever type the caller demands. So the implementation is much more restricted: the result must come from the input list, because that's the only place you know the elements have type a no matter what the caller actually instantiates this to. Only something like
foo = head
will work then.
Your RankN signature requires its argument to be such a polymorphic function, i.e. the argument can't be a [Int] -> Int but only the more restrictive [a] -> a.

What does a stand for in a data type declaration?

Normally when using type declarations we do:
function_name :: Type -> Type
However in an exercise I am trying to solve there is the following structure:
function_name :: Type a -> Type a
or explicitly as in the exercise
alphabet :: DFA a -> Alphabet a
alphabet = undefined
What does a stand for?
Short answer: it's a type variable.
At the computation level, the way we define functions is to use variables to refer to their arguments. Like this:
f x = x + 3
Here x is a variable, and its value will be chosen when the function is called. Haskell has a similar (but not identical...) mechanism in its type sublanguage. For example, you can write things like:
type F x = (x, Int, x)
type Endo a = a -> a -> a
Here again x is a variable in the first one (and a in the second), and its value will be chosen at use sites. One can also use this mechanism when defining new types. (The previous two examples just give new names to existing types, but the following does more.) One of the most basic nontrivial examples of this is the Maybe family of types:
data Maybe a = Nothing | Just a
The things on the right of the = are computation-level, so you can mostly ignore them for now, but on the left we are declaring a new family of types Maybe which accepts other types as an argument. For example, Maybe Int, Maybe (Bool, String), Maybe (Endo Char), and even passing in expressions that have variables like Maybe (x, Int, x) are all possible.
Syntactically, type constructors (things which are defined as part of the program text and that we expect the compiler to look up the definition for) start with an upper case letter and type variables (things which will be instantiated later and so don't currently have a concrete definition) start with lower case letters.
So, in the type signature you showed:
alphabet :: DFA a -> Alphabet a
I suspect there are actually two constructs new to you, not just one: first, the type variable a that you asked about, and second, the concept of type application, where we apply at the type level one "function-like" type to another. (Outside of this answer, people say "parameterized" instead of "function-like".)
...and, believe it or not, there is even a type system for types that makes sure you don't write things like these:
Int a -- Int is not parameterized, so shouldn't be applied to arguments
Int Char -- ditto
Maybe -> String -- Maybe is parameterized, so should be applied to
-- arguments, but isn't

How does return statement work in Haskell? [duplicate]

This question already has answers here:
What's so special about 'return' keyword
(3 answers)
Closed 5 years ago.
Consider these functions
f1 :: Maybe Int
f1 = return 1
f2 :: [Int]
f2 = return 1
Both have the same statement return 1. But the results are different. f1 gives value Just 1 and f2 gives value [1]
Looks like Haskell invokes two different versions of return based on return type. I like to know more about this kind of function invocation. Is there a name for this feature in programming languages?
This is a long meandering answer!
As you've probably seen from the comments and Thomas's excellent (but very technical) answer You've asked a very hard question. Well done!
Rather than try to explain the technical answer I've tried to give you a broad overview of what Haskell does behind the scenes without diving into technical detail. Hopefully it will help you to get a big picture view of what's going on.
return is an example of type inference.
Most modern languages have some notion of polymorphism. For example var x = 1 + 1 will set x equal to 2. In a statically typed language 2 will usually be an int. If you say var y = 1.0 + 1.0 then y will be a float. The operator + (which is just a function with a special syntax)
Most imperative languages, especially object oriented languages, can only do type inference one way. Every variable has a fixed type. When you call a function it looks at the types of the argument and chooses a version of that function that fits the types (or complains if it can't find one).
When you assign the result of a function to a variable the variable already has a type and if it doesn't agree with the type of the return value you get an error.
So in an imperative language the "flow" of type deduction follows time in your program Deduce the type of a variable, do something with it and deduce the type of the result. In a dynamically typed language (such as Python or javascript) the type of a variable is not assigned until the value of the variable is computed (which is why there don't seem to be types). In a statically typed language the types are worked out ahead of time (by the compiler) but the logic is the same. The compiler works out what the types of variables are going to be, but it does so by following the logic of the program in the same way as the program runs.
In Haskell the type inference also follows the logic of the program. Being Haskell it does so in a very mathematically pure way (called System F). The language of types (that is the rules by which types are deduced) are similar to Haskell itself.
Now remember Haskell is a lazy language. It doesn't work out the value of anything until it needs it. That's why it makes sense in Haskell to have infinite data structures. It never occurs to Haskell that a data structure is infinite because it doesn't bother to work it out until it needs to.
Now all that lazy magic happens at the type level too. In the same way that Haskell doesn't work out what the value of an expression is until it really needs to, Haskell doesn't work out what the type of an expression is until it really needs to.
Consider this function
func (x : y : rest) = (x,y) : func rest
func _ = []
If you ask Haskell for the type of this function it has a look at the definition, sees [] and : and deduces that it's working with lists. But it never needs to look at the types of x and y, it just knows that they have to be the same because they end up in the same list. So it deduces the type of the function as [a] -> [a] where a is a type that it hasn't bothered to work out yet.
So far no magic. But it's useful to notice the difference between this idea and how it would be done in an OO language. Haskell doesn't convert the arguments to Object, do it's thing and then convert back. Haskell just hasn't been asked explicitly what the type of the list is. So it doesn't care.
Now try typing the following into ghci
maxBound - length ""
maxBound : "Hello"
Now what just happened !? minBound bust be a Char because I put it on the front of a string and it must be an integer because I added it to 0 and got a number. Plus the two values are clearly very different.
So what is the type of minBound? Let's ask ghci!
:type minBound
minBound :: Bounded a => a
AAargh! what does that mean? Basically it means that it hasn't bothered to work out exactly what a is, but is has to be Bounded if you type :info Bounded you get three useful lines
class Bounded a where
minBound :: a
maxBound :: a
and a lot of less useful lines
So if a is Bounded there are values minBound and maxBound of type a.
In fact under the hood Bounded is just a value, it's "type" is a record with fields minBound and maxBound. Because it's a value Haskell doesn't look at it until it really needs to.
So I appear to have meandered somewhere in the region of the answer to your question. Before we move onto return (which you may have noticed from the comments is a wonderfully complex beast.) let's look at read.
ghci again
read "42" + 7
read "'H'" : "ello"
length (read "[1,2,3]")
and hopefully you won't be too surprised to find that there are definitions
read :: Read a => String -> a
class Read where
read :: String -> a
so Read a is just a record containing a single value which is a function String -> a. Its very tempting to assume that there is one read function which looks at a string, works out what type is contained in the string and returns that type. But it does the opposite. It completely ignores the string until it's needed. When the value is needed, Haskell first works out what type it's expecting, once it's done that it goes and gets the appropriate version of the read function and combines it with the string.
now consider something slightly more complex
readList :: Read a => [String] -> a
readList strs = map read strs
under the hood readList actually takes two arguments
readList' (Read a) -> [String] -> [a]
readList' {read = f} strs = map f strs
Again as Haskell is lazy it only bothers looking at the arguments when it's needs to find out the return value, at that point it knows what a is, so the compiler can go and fine the right version of Read. Until then it doesn't care.
Hopefully that's given you a bit of an idea of what's happening and why Haskell can "overload" on the return type. But it's important to remember it's not overloading in the conventional sense. Every function has only one definition. It's just that one of the arguments is a bag of functions. read_str doesn't ever know what types it's dealing with. It just knows it gets a function String -> a and some Strings, to do the application it just passes the arguments to map. map in turn doesn't even know it gets strings. When you get deeper into Haskell it becomes very important that functions don't know very much about the types they're dealing with.
Now let's look at return.
Remember how I said that the type system in Haskell was very similar to Haskell itself. Remember that in Haskell functions are just ordinary values.
Does this mean I can have a type that takes a type as an argument and returns another type? Of course it does!
You've seen some type functions Maybe takes a type a and returns another type which can either be Just a or Nothing. [] takes a type a and returns a list of as. Type functions in Haskell are usually containers. For example I could define a type function BinaryTree which stores a load of a's in a tree like structure. There are of course lots of much stranger ones.
So, if these type functions are similar to ordinary types I can have a typeclass that contains type functions. One such typeclass is Monad
class Monad m where
return a -> m a
(>>=) m a (a -> m b) -> m b
so here m is some type function. If I want to define Monad for m I need to define return and the scary looking operator below it (which is called bind)
As others have pointed out the return is a really misleading name for a fairly boring function. The team that designed Haskell have since realised their mistake and they're genuinely sorry about it. return is just an ordinary function that takes an argument and returns a Monad with that type in it. (You never asked what a Monad actually is so I'm not going to tell you)
Let's define Monad for m = Maybe!
First I need to define return. What should return x be? Remember I'm only allowed to define the function once, so I can't look at x because I don't know what type it is. I could always return Nothing, but that seems a waste of a perfectly good function. Let's define return x = Just x because that's literally the only other thing I can do.
What about the scary bind thing? what can we say about x >>= f? well x is a Maybe a of some unknown type a and f is a function that takes an a and returns a Maybe b. Somehow I need to combine these to get a Maybe b`
So I need to define Nothing >== f. I can't call f because it needs an argument of type a and I don't have a value of type a I don't even know what 'a' is. I've only got one choice which is to define
Nothing >== f = Nothing
What about Just x >>= f? Well I know x is of type a and f takes a as an argument, so I can set y = f a and deduce that y is of type b. Now I need to make a Maybe b and I've got a b so ...
Just x >>= f = Just (f x)
So I've got a Monad! what if m is List? well I can follow a similar sort of logic and define
return x = [x]
[] >>= f = []
(x : xs) >>= a = f x ++ (xs >>= f)
Hooray another Monad! It's a nice exercise to go through the steps and convince yourself that there's no other sensible way of defining this.
So what happens when I call return 1?
Nothing!
Haskell's Lazy remember. The thunk return 1 (technical term) just sits there until someone needs the value. As soon as Haskell needs the value it know what type the value should be. In particular it can deduce that m is List. Now that it knows that Haskell can find the instance of Monad for List. As soon as it does that it has access to the correct version of return.
So finally Haskell is ready To call return, which in this case returns [1]!
The return function is from the Monad class:
class Applicative m => Monad (m :: * -> *) where
...
return :: a -> m a
So return takes any value of type a and results in a value of type m a. The monad, m, as you've observed is polymorphic using the Haskell type class Monad for ad hoc polymorphism.
At this point you probably realize return is not an good, intuitive, name. It's not even a built in function or a statement like in many other languages. In fact a better-named and identically-operating function exists - pure. In almost all cases return = pure.
That is, the function return is the same as the function pure (from the Applicative class) - I often think to myself "this monadic value is purely the underlying a" and I try to use pure instead of return if there isn't already a convention in the codebase.
You can use return (or pure) for any type that is a class of Monad. This includes the Maybe monad to get a value of type Maybe a:
instance Monad Maybe where
...
return = pure -- which is from Applicative
...
instance Applicative Maybe where
pure = Just
Or for the list monad to get a value of [a]:
instance Applicative [] where
{-# INLINE pure #-}
pure x = [x]
Or, as a more complex example, Aeson's parse monad to get a value of type Parser a:
instance Applicative Parser where
pure a = Parser $ \_path _kf ks -> ks a

Haskell - Declaring the type of multiple functions

I often find myself writing multiple functions with the same type. Let's call this type FuncType. I might write something like this:
funcA :: FuncType
funcB :: FuncType
funcC :: FuncType
funcD :: FuncType
-- Implementations
This feels like a lot of unnecessary typing (typing as in tapping on the keyboard, not declaring types of functions). Is there maybe some way to do this more concisely? What I want would look something along the lines of:
(funcA, funcB, funcC, funcD) :: FuncType
-- Implementations
I really tried to google this but I came up empty. If this isn't a feature of the language, why not? Am I missing something? Am I doing something wrong if I find myself needing this?
Do what you tried without the parentheses.
funcA, funcB, funcC, funcD :: FuncType
In the Haskell 2010 report, you can see in chapter 4 (Declarations and Bindings) that a type signature (gendecl) looks like this:
vars :: [context =>] type
and vars look like this:
var-1 , … , var-n
Which is exactly the form you're looking for.
Sidenote: Haddock will apply a documentation if it finds it around that type signature to every symbol in that (vars) list.
Alternatively to MasterMastic's answer, you can also actually give the repeated type a name using a type declaration:
-- | why GoodName is a good name
type GoodName = Complicated -> Function -> Type
-- | Foo explanation.
foo :: GoodName
foo = ...
-- | Bar explanation.
bar :: GoodName
bar = ...
This way, you only need to repeat the name instead of the potentially much longer type. Benefits of this style over foo, bar :: Complicated -> Function -> Type include:
the named type serves as documentation
the named type can be reused elsewhere
the function definitions and type signatures are next to each other
you can have different haddock comments for the different functions
your source code looks more regular
if only one of the functions later gets refactored to take additional arguments, the change is more local.
Of course, you can also combine these approaches as foo, bar :: GoodName. Because of type inference, you can usually even leave out the type signature altogether and let the compiler figure out the type.

determining function behavior from the type of the function

New to Haskell so sorry if this is very basic
This example is taken from "Real World Haskell" -
ghci> :type fst
fst :: (a, b) -> a
They show the type of the fst function and then follow it with this paragraph...
"The result type of fst is a. We've already mentioned that parametric polymorphism makes the real type inaccessible: fst doesn't have enough information to construct a value of type a, nor can it turn an a into a b. So the only possible valid behaviour (omitting infinite loops or crashes) it can have is to return the first element of the pair."
I feel like I am missing the fundamental point of the paragraph, and perhaps something important about Haskell. Why couldn't the fst function return type b? Why couldn't it take the tuple as a param, but simply return an Int ( or any other type that is NOT a)? I don't understand why it MUST return type a?
Thanks
If it did any of those things, its type would change. What the quote is saying is that, given that we know fst is of type (a, b) -> a, we can make those deductions about it. If it had a different type, we would not be able to do so.
For instance, see that
snd :: (a, b) -> a
snd (x, y) = y
does not type-check, and so we know a value of type (a, b) -> a cannot behave like snd.
Parametricity is basically the fact that a polymorphic function of a certain type must obey certain laws by construction — i.e., there is no well-typed expression of that type that does not obey them. So, for it to be possible to prove things about fst with it, we must first know fst's type.
Note especially the word polymorphism there: we can't do the same kind of deductions about non-polymorphic types. For instance,
myFst :: (Int, String) -> Int
myFst (a, b) = a
type-checks, but so does
myFst :: (Int, String) -> Int
myFst (a, b) = 42
and even
myFst :: (Int, String) -> Int
myFst (a, b) = length b
Parametricity relies crucially on the fact that a polymorphic function can't "look" at the types it is called with. So the only value of type a that fst knows about is the one it's given: the first element of the tuple.
The point is that once you have that type, the implementation options are greatly limited. If you returned an Int, then your type would be (a,b) -> Int. Since a could be anything, we can't gin one up out of thin air in the implementation without resorting to undefined, and so must return the one given to us by the caller.
You should read the Theorems for Free article.
Let's try to add some more hand-waving to that already given by Real World Haskell. Lets try to convince ourselves that given that we have a function fst with type (a,b) -> a the only total function it can be is the following one:
fst (x,y) = x
First of all, we cannot return anything other then a value of type a, that is in the premise that fst has type (a,b) -> a, so we cannot have fst (x,y) = y or fst (x,y) = 1 because that does not have the correct type.
Now, as RWH says, if I give fst an (Int,Int), fst doesn't know these are Ints, furthermore, a or b are not required to belong to any type class so fst has no available values or functions associated with a or b.
So fst only knows about the a value and the b value that I give it and I can't turn b into an a (It can't make a b -> a function) so it must return the given a value.
This isn't actually just magical hand waving, one can actually deduce what possible expressions there are of a given polymorphic type. There is actually a program called djinn that does exactly that.
The point here is that both a and b are type variables (that might be the same, but that's not needed). Anyway, since for a given tuple of two elements, fst returns always the first element, the returned type must be always the same as the type for the first element.
The fundamental thing you're probably missing is this:
In most programming languages, if you say "this function returns any type", it means that the function can decide what type of value it actually returns.
In Haskell, if you say "this function returns any type", it means that the caller gets to decide what type that should be. (!)
So if I you write foo :: Int -> x, it can't just return a String, because I might not ask it for a String. I might ask for a Customer, or a ThreadId, or anything.
Obviously, there's no way that foo can know how to create a value of every possible type, even types that don't exist yet. In short, it is impossible to write foo. Everything you try will give you type errors, and won't compile.
(Caveat: There is a way to do it. foo could loop forever, or throw an exception. But it cannot return a valid value.)
There's no way for a function to be able to create values of any possible type. But it's perfectly possible for a function to move data around without caring what type it is. Therefore, if you see a function that accepts any kind of data, the only thing it can be doing with it is to move it around.
Alternatively, if the type has to belong to a specific class, then the function can use the methods of that class on it. (Could. It doesn't have to, but it can if it wants to.)
Fundamentally, this is why you can actually tell what a function does just by looking at its type signature. The type signature tells you what the function "knows" about the data it's going to be given, and hence what possible operations it might perform. This is why searching for a Haskell function by its type signature is so damned useful.
You've heard the expression "in Haskell, if it compiles, it usually works right"? Well, this is why. ;-)

Resources