How should types be used in Haskell type classes? - haskell

I'm new to Haskell, and a little confused about how type classes work. Here's a simplified example of something I'm trying to do:
data ListOfInts = ListOfInts {value :: [Int]}
data ListOfDoubles = ListOfDoubles {value :: [Double]}
class Incrementable a where
increment :: a -> a
instance Incrementable ListOfInts where
increment ints = map (\x -> x + 1) ints
instance Incrementable ListOfDoubles where
increment doubles = map (\x -> x + 1) doubles
(I realize that incrementing each element of a list can be done very simply, but this is just a simplified version of a more complex problem.)
The compiler tells me that I have multiple declarations of value. If I change the definitions of ListOfInts and ListOfDoubles as follows:
type ListOfInts = [Int]
type ListOfDoubles = [Double]
Then the compiler says "Illegal instance declaration for 'Incrementable ListOfInts'" (and similarly for ListOfDoubles. If I use newtype, e.g., newtype ListOfInts = ListOfInts [Int], then the compiler tells me "Couldn't match expected type 'ListOfInts' with actual type '[b0]'" (and similarly for ListOfDoubles.
My understanding of type classes is that they facilitate polymorphism, but I'm clearly missing something. In the first example above, does the compiler just see that the type parameter a refers to a record with a field called value and that it appears I'm trying to define increment for this type in multiple ways (rather than seeing two different types, one which has a field whose type of a list of Ints, and the other whose type is a list of Doubles)? And similarly for the other attempts?
Thanks in advance.

You're really seeing two separate problems, so I'll address them as such.
The first one is with the value field. Haskell records work in a slightly peculiar way: when you name a field, it is automatically added to the current scope as a function. Essentially, you can think of
data ListOfInts = ListOfInts {value :: [Int]}
as syntax sugar for:
data ListOfInts = ListOfInts [Int]
value :: ListOfInt -> [Int]
value (ListOfInts v) = v
So having two records with the same field name is just like having two different functions with the same name--they overlap. This is why your first error tells you that you've declared values multiple times.
The way to fix this would be to define your types without using the record syntax, as I did above:
data ListOfInts = ListOfInts [Int]
data ListOfDoubles = ListOfDoubles [Double]
When you used type instead of data, you simply created a type synonym rather than a new type. Using
type ListOfInts = [Int]
means that ListOfInts is the same as just [Int]. For various reasons, you can't use type synonyms in class instances by default. This makes sense--it would be very easy to make a mistake like trying to write an instance for [Int] as well as one for ListOfInts, which would break.
Using data to wrap a single type like [Int] or [Double] is the same as using newtype. However, newtype has the advantage that it carries no runtime overhead at all. So the best way to write these types would indeed be with newtype:
newtype ListOfInts = ListOfInts [Int]
newtype ListOfDoubles = ListOfDoubles [Double]
An important thing to note is that when you use data or newtype, you also have to "unwrap" the type if you want to get at its content. You can do this with pattern matching:
instance Incrementable ListOfInts where
increment (ListOfInts ls) = ListOfInts (map (\ x -> x + 1) ls)
This unwraps the ListOfInts, maps a function over its contents and wraps it back up.
As long as you unwrap the value this way, your instances should work.
On a side note, you can write map (\ x -> x + 1) as map (+ 1), using something that is called an "operator section". All this means is that you implicitly create a lambda filling in whichever argument of the operator is missing. Most people find the map (+ 1) version easier to read because there is less unnecessary noise.

Related

Creating a conditioned Arbitrary instance ( * Ambiguous type variable `a' arising from a use of `quickCheck')

I have this test I want to make:
prop_inverse_stringsToInts st = isDigitList st ==> st == map show (stringsToInts st)
Which is testing a function that converts a list of Strings to a list of Integers, but of course the strings need to be digits so I created a pre-condition that checks that using the isDigitList function I made, but the condition is too specific and quickCheck gives up : "*** Gave up! Passed only 43 tests; 1000 discarded tests."
So I wanted to create an Arbitrary instance for my case, but the thing is I am inexperienced with working with Arbitrary, so I don't really know how to do this and every time I shuffle code I get a new error. All I want is an Arbitrary that only returns the Foo [String] if it passes the isDigitList (which receives a [String] and returns a Bool). So far I have something like this :
Foo a = Foo [String] deriving (Show,Eq)
instance (Arbitrary a) => Arbitrary (Foo a ) where
arbitrary = do
st <- (arbitrary :: Gen [String])
if isDigitList st
then do return (Foo st)
else do return (Foo []) -- This is probably a bad idea
I altered my property to :
prop_inverse_stringsToInts :: Foo a -> Bool
prop_inverse_stringsToInts (Foo st) = st == map show (stringsToInts st)
But now I am getting the error "* Ambiguous type variable a0' arising from a use of `quickCheck'" even though I am running quickCheck like this : > quickCheck (prop_inverse_stringsToInts :: Foo a -> Bool)
Can someone help please? Thank you in advance!
It seems you know the basics, but I'll repeat them here just to be sure. There are two ways to get QuickCheck to generate the inputs you want:
Have it generate some inputs and then filter out ones you don't want, or
Have it generate only the inputs you want.
You started with option 1, but as you saw, that didn't work out great. Compared to all possible lists of String, there really aren't that many that are digit lists. The better option is to generate only the inputs you want.
To succeed at option 2, you need to make a generator, which would be a value of type Gen [String] that generates lists of Strings that fit your criteria. The generator you propose still uses the method of filtering, so you may want to try a different approach. Consider instead, something like:
genDigitStrings :: Gen [String]
genDigitStrings = do
intList <- arbitrary :: Gen [Integer]
return $ fmap show intList
This generator produces arbitrary lists of Strings that are always shown integers, meaning that they will always be digit lists. You can then go ahead and insert this into an Arbitrary instance for some newtype if you want.
For your own sanity, you can even check your work with a test like this:
propReallyActuallyDigitStrings = forAll genDigitStrings isDigitList
If that passes, you have some confidence that your generator really only produces digit lists, and if it fails, then you should adjust your generator.

How does the :: operator syntax work in the context of bounded typeclass?

I'm learning Haskell and trying to understand the reasoning behind it's syntax design at the same time. Most of the syntax is beautiful.
But since :: normally is like a type annotation, How is it that this works:
Input: minBound::Int
Output: -2147483648
There is no separate operator: :: is a type annotation in that example. Perhaps the best way to understand this is to consider this code:
main = print (f minBound)
f :: Int -> Int
f = id
This also prints -2147483648. The use of minBound is inferred to be an Int because it is the parameter to f. Once the type has been inferred, the value for that type is known.
Now, back to:
main = print (minBound :: Int)
This works in the same way, except that minBound is known to be an Int because of the type annotation, rather than for some more complex reason. The :: isn't some binary operation; it just directs the compiler that the expression minBound has the type Int. Once again, since the type is known, the value can be determined from the type class.
:: still means "has type" in that example.
There are two ways you can use :: to write down type information. Type declarations, and inline type annotations. Presumably you've been used to seeing type declarations, as in:
plusOne :: Integer -> Integer
plusOne = (+1)
Here the plusOne :: Integer -> Integer line is a separate declaration about the identifier plusOne, informing the compiler what its type should be. It is then actually defined on the following line in another declaration.
The other way you can use :: is that you can embed type information in the middle of any expression. Any expression can be followed by :: and then a type, and it means the same thing as the expression on its own except with the additional constraint that it must have the given type. For example:
foo = ('a', 2) :: (Char, Integer)
bar = ('a', 2 :: Integer)
Note that for foo I attached the entire expression, so it is very little different from having used a separate foo :: (Char, Integer) declaration. bar is more interesting, since I gave a type annotation for just the 2 but used that within a larger expression (for the whole pair). 2 :: Integer is still an expression for the value 2; :: is not an operator that takes 2 as input and computes some result. Indeed if the 2 were already used in a context that requires it to be an Integer then the :: Integer annotation changes nothing at all. But because 2 is normally polymorphic in Haskell (it could fit into a context requiring an Integer, or a Double, or a Complex Float) the type annotation pins down that the type of this particular expression is Integer.
The use is that it avoids you having to restructure your code to have a separate declaration for the expression you want to attach a type to. To do that with my simple example would have required something like this:
two :: Integer
two = 2
baz = ('a', two)
Which adds a relatively large amount of extra code just to have something to attach :: Integer to. It also means when you're reading bar, you have to go read a whole separate definition to know what the second element of the pair is, instead of it being clearly stated right there.
So now we can answer your direct question. :: has no special or particular meaning with the Bounded type class or with minBound in particular. However it's useful with minBound (and other type class methods) because the whole point of type classes is to have overloaded names that do different things depending on the type. So selecting the type you want is useful!
minBound :: Int is just an expression using the value of minBound under the constraint that this particular time minBound is used as an Int, and so the value is -2147483648. As opposed to minBound :: Char which is '\NUL', or minBound :: Bool which is False.
None of those options mean anything different from using minBound where there was already some context requiring it to be an Int, or Char, or Bool; it's just a very quick and simple way of adding that context if there isn't one already.
It's worth being clear that both forms of :: are not operators as such. There's nothing terribly wrong with informally using the word operator for it, but be aware that "operator" has a specific meaning in Haskell; it refers to symbolic function names like +, *, &&, etc. Operators are first-class citizens of Haskell: we can bind them to variables1 and pass them around. For example I can do:
(|+|) = (+)
x = 1 |+| 2
But you cannot do this with ::. It is "hard-wired" into the language, just as the = symbol used for introducing definitions is, or the module Main ( main ) where syntax for module headers. As such there are lots of things that are true about Haskell operators that are not true about ::, so you need to be careful not to confuse yourself or others when you use the word "operator" informally to include ::.
1 Actually an operator is just a particular kind of variable name that is applied by writing it between two arguments instead of before them. The same function can be bound to operator and ordinary variables, even at the same time.
Just to add another example, with Monads you can play a little like this:
import Control.Monad
anyMonad :: (Monad m) => Int -> m Int
anyMonad x = (pure x) >>= (\x -> pure (x*x)) >>= (\x -> pure (x+2))
$> anyMonad 4 :: [Int]
=> [18]
$> anyMonad 4 :: Either a Int
=> Right 18
$> anyMonad 4 :: Maybe Int
=> Just 18
it's a generic example telling you that the functionality may change with the type, another example:

Is it possible to define a list recursively in Haskell?

In several programming languages (including JavaScript, Python, and Ruby), it's possible to place a list inside itself, which can be useful when using lists to represent infinitely-detailed fractals. However, I tried doing this in Haskell, and it did not work as I expected:
--aList!!0!!0!!1 should be 1, since aList is recursively defined: the first element of aList is aList.
main = putStrLn $ show $ aList!!0!!0!!1
aList = [aList, 1]
Instead of printing 1, the program produced this compiler error:
[1 of 1] Compiling Main ( prog.hs, prog.o )
prog.hs:3:12:
Occurs check: cannot construct the infinite type: t0 = [t0]
In the expression: aList
In the expression: [aList, 1]
In an equation for `aList': aList = [aList, 1]
Is it possible to put an list inside itself in Haskell, as I'm attempting to do here?
No, you can't. First off, there's a slight terminological confusion: what you have there are lists, not arrays (which Haskell also has) , although the point stands either way. So then, as with all things Haskell, you must ask yourself: what would the type of aList = [aList, 1] be?
Let's consider the simpler case of aList = [aList]. We know that aList must be a list of something, so aList :: [α] for some type α. What's α? As the type of the list elements, we know that α must be the type of aList; that is, α ~ [α], where ~ represents type equality. So α ~ [α] ~ [[α]] ~ [[[α]]] ~ ⋯ ~ [⋯[α]⋯] ~ ⋯. This is, indeed, an infinite type, and Haskell forbids such things.
In the case of the value aList = [aList, 1], you also have the restriction that 1 :: α, but all that that lets us conclude is that there must be a Num α constraint (Num α => [⋯[α]⋯]), which doesn't change anything.
The obvious next three questions are:
Why do Haskell lists only contain one type of element?
Why does Haskell forbid infinite types?
What can I do about this?
Let's tackle those in order.
Number one: Why do Haskell lists only contain one type of element? This is because of Haskell's type system. Suppose you have a list of values of different types: [False,1,2.0,'c']. What's the type of the function someElement n = [False,1,2.0,'c'] !! n? There isn't one, because you couldn't know what type you'd get back. So what could you do with that value, anyway? You don't know anything about it, after all!
Number two: Why does Haskell forbid infinite types? The problem with infinite types is that they don't add many capabilities (you can always wrap them in a new type; see below), and they make some genuine bugs type-check. For example, in the question "Why does this Haskell code produce the ‘infinite type’ error?", the non-existence of infinite types precluded a buggy implementation of intersperse (and would have even without the explicit type signature).
Number three: What can I do about this? If you want to fake an infinite type in Haskell, you must use a recursive data type. The data type prevents the type from having a truly infinite expansion, and the explicitness avoids the accidental bugs mentioned above. So we can define a newtype for an infinitely nested list as follows:
Prelude> newtype INL a = MkINL [INL a] deriving Show
Prelude> let aList = MkINL [aList]
Prelude> :t aList
aList :: INL a
Prelude> aList
MkINL [MkINL [MkINL [MkINL ^CInterrupted.
This got us our infinitely-nested list that we wanted—printing it out is never going to terminate—but none of the types were infinite. (INL a is isomorphic to [INL a], but it's not equal to it. If you're curious about this, the difference is between isorecursive types (what Haskell has) and equirecursive types (which allow infinite types).)
But note that this type isn't very useful; the only lists it contains are either infinitely nested things like aList, or variously nested collections of the empty list. There's no way to get a base case of a value of type a into one of the lists:
Prelude> MkINL [()]
<interactive>:15:8:
Couldn't match expected type `INL a0' with actual type `()'
In the expression: ()
In the first argument of `MkINL', namely `[()]'
In the expression: MkINL [()]
So the list you want is an arbitrarily nested list. The 99 Haskell Problems has a question about these, which requires defining a new data type:
data NestedList a = Elem a | List [NestedList a]
Every element of NestedList a is either a plain value of type a, or a list of more NestedList as. (This is the same thing as an arbitrarily-branching tree which only stores data in its leaves.) Then you have
Prelude> data NestedList a = Elem a | List [NestedList a] deriving Show
Prelude> let aList = List [aList, Elem 1]
Prelude> :t aList
aList :: NestedList Integer
Prelude> aList
List [List [List [List ^CInterrupted.
You'll have to define your own lookup function now, and note that it will probably have type NestedList a -> Int -> Maybe (NestedList a)—the Maybe is for dealing with out-of-range integers, but the important part is that it can't just return an a. After all, aList ! 0 is not an integer!
Yes. If you want a value that contains itself, you'll need a type that contains itself. This is no problem; for example, you might like rose trees, defined roughly like this in Data.Tree:
data Tree a = Node a [Tree a]
Now we can write:
recursiveTree = Node 1 [recursiveTree]
This isn't possible with the list type in Haskell, since each element has to be of the same type, but you could create a data type to do it. I'm not exactly sure why you'd want to, though.
data Nested a
= Value a
| List [Nested a]
deriving (Eq, Show)
nested :: Nested Int
nested = List [nested, Value 1]
(!) :: Nested a -> Int -> Nested a
(!) (Value _) _ = undefined
(!) (List xs) n = xs !! n
main = print $ nested ! 0 ! 0 ! 1
This will print out Value 1, and this structure could be of some use, but I'd imagine it's pretty limited.
There were several answers from "yes you can" to "no you absolutely cannot". Well, both are right, because all of them address different aspects of your question.
One other way to add "array" to itself, is permit a list of anything.
{-# LANGUAGE ExistentialQuantification #-}
data T = forall a. T a
arr :: [T]
arr = [T arr, T 1]
So, this adds arr to itself, but you cannot do anything else with it, except prove it is a valid construct and compile it.
Since Haskell is strongly typed, accessing list elements gives you T, and you could extract the contained value. But what is the type of that value? It is "forall a. a" - can be any type, which in essence means there are no functions at all that can do anything with it, not even print, because that would require a function that can convert any type a to String. Note that this is not specific to Haskell - even in dynamic languages the problem exists; there is no way to figure out the type of arr !! 1, you only assume it is a Int. What makes Haskell different to that other language, is that it does not let you use the function unless you can explain the type of the expression.
Other examples here define inductive types, which is not exactly what you are asking about, but they show the tractable treatment of self-referencing.
And here is how you could actually make a sensible construct:
{-# LANGUAGE ExistentialQuantification #-}
data T = forall a. Show a => T a
instance Show T where -- this also makes Show [T],
-- because Show a => Show [a] is defined in standard library
show (T x) = show x
arr :: [T]
arr = [T arr, T 1]
main = print $ arr !! 1
Now the inner value wrapped by T is restricted to be any instance of Show ("implementation of Show interface" in OOP parlance), so you can at least print the contents of the list.
Note that earlier we could not include arr in itself only because there was nothing common between a and [a]. But the latter example is a valid construct once you can determine what's the common operation that all the elements in the list support. If you can define such a function for [T], then you can include arr in the list of itself - this function determines what's common between certain kinds of a and [a].
No. We could emulate:
data ValueRef a = Ref | Value a deriving Show
lref :: [ValueRef Int]
lref = [Value 2, Ref, Value 1]
getValue :: [ValueRef a] -> Int -> [ValueRef a]
getValue lref index = case lref !! index of
Ref -> lref
a -> [a]
and have results:
>getValue lref 0
[Value 2]
>getValue lref 1
[Value 2,Ref,Value 1]
Sure, we could reuse Maybe a instead of ValueRef a

Overload built in function in Haskell

In Haskell, how can one overload a built in function such as !!?
I originally was trying to figure out how to overload the built in function !! to support by own data types. Specifically, !! is of the type:
[a] -> Int -> a
and I want to preserve it's existing functionality, but also be able to call it where its type signature looks more like
MyType1 -> MyType2 -> MyType3
I originally wanted to do this because MyType1 is like a list, and I wanted to use the !! operator because my operation is very similar to selecting an item from a list.
If I was overloading something like + I could just add an instance of my function to the applicable type class, but I don't think that is an option here.
I'm not convinced I actually even want to overload this function anymore, but I am still interested in how it would be done. Actually, comments on if overloading an operator such as !! is even a good idea would be appreciated as well.
In Haskell, nearly all operators are library-defined. Many of the ones you use the most are defined in the 'standard library' of the Prelude module that is imported by default. Gabriel's answer shows how to avoid importing some of those definitions so you can make your own.
That's not overloading though, because the operator still just means one thing; the new meaning you define for it. The primary method that Haskell provides for overloading, i.e. using an operator in such a way that it has different implementations for different types, is the type class mechanism.
A type class identifies a group of types that support some common functions. When you use those functions with a type, Haskell figures out the correct instance of the type class that applies to your usage and makes sure the correct implementation of the functions is used. Most type classes have just a few functions, some just one or two, that need to be implemented to make a new instance. Many of them offer a lot of secondary functions implemented in terms of the core ones as well, and you can use all of them with a type you make an instance of the class.
It so happens that others have made types that behave quite a bit like lists, and so there's already a type class called ListLike. I'm not sure exactly how close your type is to a list, so it may not be a perfect fit for ListLike, but you should look at it as it will give you a lot of capability if you can make your type a ListLike instance.
You can't actually overload an existing non-typeclass function in Haskell.
What you can do is define a new function in a new type class, which is general enough to encompass both the original function and the new definition you want as an overload. You can give it the same name as the standard function, and avoid importing the standard one. That means in your module you can use the name !! to get both the functionality of your new definition, and the original definition (the resolution will be directed by the types).
Example:
{-# LANGUAGE TypeFamilies #-}
import Prelude hiding ((!!))
import qualified Prelude
class Indexable a where
type Index a
type Elem a
(!!) :: a -> Index a -> Elem a
instance Indexable [a] where
type Index [a] = Int
type Elem [a] = a
(!!) = (Prelude.!!)
newtype MyType1 = MyType1 String
deriving Show
newtype MyType2 = MyType2 Int
deriving Show
newtype MyType3 = MyType3 Char
deriving Show
instance Indexable MyType1 where
type Index MyType1 = MyType2
type Elem MyType1 = MyType3
MyType1 cs !! MyType2 i = MyType3 $ cs !! i
(I've used type families to imply that for a given type that can be indexed, the type of the indices and the type of the elements automatically follows; this could of course be done differently, but going into that in more detail is getting side-tracked from the overload question)
Then:
*Main> :t (!!)
(!!) :: Indexable a => a -> Index a -> Elem a
*Main> :t ([] !!)
([] !!) :: Int -> a
*Main> :t (MyType1 "" !!)
(MyType1 "" !!) :: MyType2 -> MyType3
*Main> [0, 1, 2, 3, 4] !! 2
2
*Main> MyType1 "abcdefg" !! MyType2 3
MyType3 'd'
It should be emphasised that this has done absolutely nothing to the existing !! function defined in the prelude, nor to any other module that uses it. The !! defined here is a new and entirely unrelated function, which just happens to have the same name and to delegate to Prelude.!! in one particular instance. No existing code will be able to start using !! on MyType1 without modification (though other modules you can change can of course import your new !! to get this functionality). Any code that imports this module will either have to module-qualify all uses of !! or else use the same import Prelude hiding ((!!)) line to hide the original one.
Hide the Prelude's (!!) operator and you can define your own (!!) operator:
import Prelude hiding ((!!))
(!!) :: MyType1 -> MyType2 -> MyType3
x !! i = ... -- Go wild!
You can even make a type class for your new (!!) operator if you prefer.

what is [a] as a type in Haskell?

This question is about type in Haskell programming language.
When I type
:t []
I get the return as:
[] :: [a]
What is [a]?
Rewriting it like so might make things clearer:
[] :: forall a. [a]
So, since it doesn't contain any value, haskell can't decide on a type and leaves it open. If you use it in a typed expression, however, like
x = []
f :: [Int] -> [Int]
f l = l
y = f x
it automatically gets resolved to [Int], since it is used as this type.
It's a placeholder. It basically means any type could go there. In other words, if you had a function
someFunc :: [Int] -> ()
You could pass [] to it because [] is [a], which will match [Int] (by replacing the a placeholder with the concrete Int type).
Now if you look at, say, id, you'll find it has the type a -> a. This means that it's a function that takes an object of any type, and returns an object of the same type. Interestingly, because the function knows absolutely nothing about the object it's given (since it has no constraints on the type), you know that this function has to do either of two things:
Return the input object, or
Return ⊥ (bottom).

Resources