Studying Haskell first principles. Absolute beginner in Haskell.
If:
data A
data B
func :: A -> B
func = undefined
What would the actual function be? Worked though load of exercises with great result (also thanks to you) but again I am stuck. Does A -> B indicate two different types like 'String' -> 'Char'? Just trying to wrap my head around it.
No, (concrete) types start with an Uppercase. So A -> B means the types A and B you have defined (well not defined here) with your data A = ... expressions, like for instance:
data A = Foo | Bar Int | Qux String A
In case the signature contains an identifier with a lowercase, it is a type variable. For instance foo :: a -> b, means a and b can be substuted by any type. So foo is a function that can be A -> B, but also A -> Int, Char -> B, and Char -> Int.
You can also add type constraints to the signature to restrict the types for which for instance a and b can be used. Like foo :: (Show a, Num b) => a -> b restricts a and b, such that there should exist an instance Show a and instance Num b for the types a and b such that foo is defined over these types.
Thanks Willem, Chepner. Your answers helped me out to conjure up:
data A
data B
funcAJ :: A -> B
funcAJ a = a
where a = b
b = undefined
This typechecks as funcAJ :: A -> B, which I understand. Thanks so much!
Related
I'm trying to get a grip on how tuples work in Haskell.
I came across this type constructor leftRight :: (Either a b -> c) -> (a -> c, b -> c) and I'm struggling to see what it does.
So we have (Either a b -> c)which means that either a is applied to c or b is applied to c. But the output is a tuple?
Does that mean that it splits the function so that left side of the tuple takes in argument given at a and right side takes argument given at right?
How would this look in code?
"I came across this type constructor..."
It's not a type constructor - it's a function type declaration.
The -> separates out the parameter types. The final one is the return type, and the previous ones are the input types.
Hence leftRight :: (Either a b -> c) -> (a -> c, b -> c) takes one input and returns one output.
Input function: (Either a b -> c)
Output function pair: (a -> c, b -> c)
The parentheses contain the functions.
The first function takes an Either type (left value is the error type, a, and the right value is the OK type, 'b' - it helps me to think of the latin, sinister for left, and dexter for right - your mileage may vary) as the input and returns something of type c.
The second function comes as a tuple of two separate functions, one is a -> c, and one is b -> c.
A concrete version: type a is a String to contain my error message, type bis an Int, and type c is another string.
leftRight :: (Either String Int -> String) -> (String -> String, Int -> String)
So we have Either a b -> c which means that either a is applied to c or b is applied to c
Wrong, or at least badly worded. Nothing is “applied to c” here.
What it actually means is: the function can accept an a-value or a b-value, and in either case produces a c-value.
This is equivalent to having both a function that accepts only a-values and gives c-results, and one that accepts only b-values and gives c-results. The tuple groups both of these functions together.
It might help to look at an example to illustrate:
fryPancake :: Either Butter Margarine -> Pancake
[Assume we've already taken care of the flour, eggs etc. in the batter]
From this you can obtain both
fryPancakeWithButter :: Butter -> Pancake
fryPancakeWithButter b = fryPancake (Left b)
fryPancakeWithMargarine :: Margarine -> Pancake
fryPancakeWithMargarine m = fryPancake (Right m)
Now you just group both of these together:
fryPancake' :: (Butter -> Pancake, Margarine -> Pancake)
fryPancake' = (fryPancakeWithButter, fryPancakeWithMargarine)
...which is the same as
fryPancake' = leftRight fryPancake
The input to leftRight is a function and the output is two functions. The tuple is barely relevant, except that it groups the two functions together into a single output, so leftRight can return both of them at once.
One function's type is a -> c and the other one's type is b -> c. Presumably, the first function wraps the a in Left and then calls the original function, and the second one wraps the b in Right and then calls the original function:
leftRight :: (Either a b -> c) -> (a -> c, b -> c)
leftRight original = (leftFunc, rightFunc)
where
leftFunc aVal = original (Left aVal)
rightFunc bVal = original (Right bVal)
The key is to use function composition. A function of type a -> c can be created from functions of type a -> Either a b and Either a b -> c. You have Left :: a -> Either a b and you have the argument f :: Either a b -> c passed to leftRight.
The same argument lets you construct a function of type b -> c similarly. This gives you
leftRight :: (Either a b -> c) -> (a -> c, b -> c)
leftRight f = let g1 = ...
g2 = ...
in (g1, g2)
I leave the definitions of g1 and g2 as an exercise.
I need to define a Union Type which the set of the type includes
a -> b OR a -> IO b
a -> b || a -> IO b
or
a -> b | IO b
foo :: (a -> b | IO b) -> IO (R a) -> IO (R b)
I tried data unionType b = b | IO b that does not work.
Not a data constructor: ‘b’parser
No quick fixes available
Is it possible in Haskell?
In Haskell, a sum type (the standard term for a disjoint union type) requires explicit "constructors" for its components, so you need to write something like:
data BarType b = BarPure b | BarIO (IO b)
This defines a type BarType, and it also defines constructors BarPure and BarIO for use in constructing values of this type:
val1, val2 :: BarType String
val1 = BarPure "pure"
val2 = BarIO getLine
and consuming values of this type via case-matching:
runBar :: BarType b -> IO b
runBar barb = case barb of
BarPure s -> pure s
BarIO act -> act
There are two issues: On the one hand your type must be upper-case, that is UnionType. Second, you need to define type constructors to be able to create a value of said data type. So the closest would be e.g.
data UnionType b = Left b | Right (IO b)
Here I chose the arbitrary names Left and Right for the constructors, but you can use any you like.
If the Left/Right constructors seem familiar to you, that is because Either uses these by default, and can do exactly the same with a slightly "cheaper" type synonym:
type UnionType b = Either b (IO b)
Of course in both cases we have to deconstruct the type to get to the actual values of b and IO b.
EDIT: As #leftroundabout mentioned, it is not very convenient to define a data type with type constructors called Left and Right, as these constructors are already used with the built in Either.
something :: a -> (a -> ())
Is there a name/concept for something, the function that takes an a and returns a function from a to unit?
That is given an a, it returns a sink/consumer of a?
Is something just a -> a -> (), a bi-consumer of a?
.
What about:
somethingElse :: a -> (a -> a)
the function from a to a function from a to a?
somethingElse is basically a combiner or binary operator on a, a -> a -> a, right?
All possible implementations of something are equivalent to
sink :: a -> a -> ()
sink x y = ()
which you could also write as
sink = const $ const ()
As you can imagine, this is not a very frequently used function (it is guaranteed to never do anything interesting), and so there is no special name for it.
Your second question, about a -> a -> a, is more interesting. If the function is to be polymorphic, i.e. to work over any a at all, there are just two possible implementations:
first x y = x
second x y = y
But this type can be specialized to do something interesting for more specific a types.
(+) :: Int -> Int -> Int
is one example of such a specialization. Indeed this is the type of a binary operator, and any binary operator taking and returning a values has this type, or a specialization of it.
Functions of this type are related to Monoid and to Semigroup, in a way, but not all such functions meet the rules necessary to be part of a Monoid or Semigroup instance.
Super basic question - but I can't seem to get a clear answer. The below function won't compile:
randomfunc :: a -> a -> b
randomfunc e1 e2
| e1 > 2 && e2 > 2 = "Both greater"
| otherwise = "Not both greater"
main = do
let x = randomfunc 2 1
putStrLn $ show x
I'm confused as to why this won't work. Both parameters are type 'a' (Ints) and the return parameter is type 'b' (String)?
Error:
"Couldn't match expected type ‘b’ with actual type ‘[Char]’"
Not quite. Your function signature indicates: for all types a and b, randomfunc will return something of type b if given two things of type a.
However, randomFunc returns a String ([Char]). And since you compare e1 with 2 each other, you cannot use all a's, only those that can be used with >:
(>) :: Ord a => a -> a -> Bool
Note that e1 > 2 also needs a way to create such an an a from 2:
(> 2) :: (Num a, Ord a) => a -> Bool
So either use a specific type, or make sure that you handle all those constraints correctly:
randomfunc :: Int -> Int -> String
randomFunc :: (Ord a, Num a) => a -> a -> String
Both parameters are type 'a' (Ints) and the return parameter is type 'b' (String)?
In a Haskell type signature, when you write names that begin with a lowercase letter such as a, the compiler implicitly adds forall a. to the beginning of the type. So, this is what the compiler actually sees:
randomfunc :: forall a b. a -> a -> b
The type signature claims that your function will work for whatever ("for all") types a and b the caller throws at you. But this is not true for your function, since it only works on Int and String respectively.
You need to make your type more specific:
randomfunc :: Int -> Int -> String
On the other hand, perhaps you intended to ask the compiler to fill out a and b for you automatically, rather than to claim that it will work for all a and b. In that case, what you are really looking for is the PartialTypeSignatures feature:
{-# LANGUAGE PartialTypeSignatures #-}
randomfunc :: _a -> _a -> _b
Still new to Haskell, I have hit a wall with the following:
I am trying to define some type classes to generalize a bunch of functions that use gaussian elimination to solve linear systems of equations.
Given a linear system
M x = k
the type a of the elements m(i,j) \elem M can be different from the type b of x and k. To be able to solve the system, a should be an instance of Num and b should have multiplication/addition operators with b, like in the following:
class MixedRing b where
(.+.) :: b -> b -> b
(.*.) :: (Num a) => b -> a -> b
(./.) :: (Num a) => b -> a -> b
Now, even in the most trivial implementation of these operators, I'll get Could not deduce a ~ Int. a is a rigid type variable errors (Let's forget about ./. which requires Fractional)
data Wrap = W { get :: Int }
instance MixedRing Wrap where
(.+.) w1 w2 = W $ (get w1) + (get w2)
(.*.) w s = W $ ((get w) * s)
I have read several tutorials on type classes but I can find no pointer to what actually goes wrong.
Let us have a look at the type of the implementation that you would have to provide for (.*.) to make Wrap an instance of MixedRing. Substituting Wrap for b in the type of the method yields
(.*.) :: Num a => Wrap -> a -> Wrap
As Wrap is isomorphic to Int and to not have to think about wrapping and unwrapping with Wrap and get, let us reduce our goal to finding an implementation of
(.*.) :: Num a => Int -> a -> Int
(You see that this doesn't make the challenge any easier or harder, don't you?)
Now, observe that such an implementation will need to be able to operate on all types a that happen to be in the type class Num. (This is what a type variable in such a type denotes: universal quantification.) Note: this is not the same (actually, it's the opposite) of saying that your implementation can itself choose what a to operate on); yet that is what you seem to suggest in your question: that your implementation should be allowed to pick Int as a choice for a.
Now, as you want to implement this particular (.*.) in terms of the (*) for values of type Int, we need something of the form
n .*. s = n * f s
with
f :: Num a => a -> Int
I cannot think of a function that converts from an arbitary Num-type a to Int in a meaningful way. I'd therefore say that there is no meaningful way to make Int (and, hence, Wrap) an instance of MixedRing; that is, not such that the instance behaves as you would probably expect it to do.
How about something like:
class (Num a) => MixedRing a b where
(.+.) :: b -> b -> b
(.*.) :: b -> a -> b
(./.) :: b -> a -> b
You'll need the MultiParamTypeClasses extension.
By the way, it seems to me that the mathematical structure you're trying to model is really module, not a ring. With the type variables given above, one says that b is an a-module.
Your implementation is not polymorphic enough.
The rule is, if you write a in the class definition, you can't use a concrete type in the instance. Because the instance must conform to the class and the class promised to accept any a that is Num.
To put it differently: Exactly the class variable is it that must be instantiated with a concrete type in an instance definition.
Have you tried:
data Wrap a = W { get :: a }
Note that once Wrap a is an instance, you can still use it with functions that accept only Wrap Int.