how do I get my literal to be a num in haskell - haskell

So I'm quite the newb in haskell and questions abound. I've been reading through a couple books and trying to do a few things on my own, can someone please explain to me why this is complaining that the literal doesn't implement eq, I understand why eq is necessary- but I don't understand why this is seen as a literal rather than a num or how I change that.
generateListOfRandoms :: a -> b -> c -> d -> [(d, (a, b))]
generateListOfRandoms _ _ 0 _ = []
generateListOfRandoms rangeStart rangeEnd numberOfRandoms randGenerator =
(randGenerator, (rangeStart,rangeEnd)) : generateListOfRandoms rangeStart rangeEnd (numberOfRandoms-1) randGenerator
I'm sure my function is going to fail in other ways when I try giving it an IO function as some of you could guess, but I'm confused right now why I get this error:
src\Main.hs:23:27:
No instance for (Eq c)
arising from the literal `0'
In the pattern: 0
In an equation for `generateListOfRandoms':
generateListOfRandoms _ _ 0 _ = []

If you use a numeric literal, the type of the corresponding argument must belong to the Num class. Also, since you are pattern-matching against a numeric literal, you need the type to belong to the Eq class. You have to add these constraints to your type signature,
generateListOfRandoms :: (Num c, Eq c) => a -> b -> c -> d -> [(d, (a, b))]
If you're not using GHC-7.4, the Eq constraint is implied by the Num constraint, that has recently been changed, so now you have to state both explicitly if you use both.

Related

Why do some function calls fail to work without a type application?

I am having trouble understanding how type applications work. Why can sing in refuteRefuteKnockable be used without a type application when the call to sing in knockableOrOpened will fail to type check without a type application?
refuteRefuteKnockable :: SingI s => Refuted (Refuted (Knockable s)) -> Knockable s
refuteRefuteKnockable rrK =
case isKnockable $ sing of
Proved k -> k
Disproved rK -> absurd $ rrK rK
knockableOrOpened :: forall s. SingI s => Or Knockable ((:~:) Opened) s
knockableOrOpened =
case sing #s of
SOpened -> OrRight $ Refl
SClosed -> OrLeft KnockClosed
SLocked -> OrLeft KnockLocked
I am working from the following codebase: https://github.com/mstksg/inCode/blob/master/code-samples/singletons/Door3.hs
Type inference is the cause. This type contains s ...
refuteRefuteKnockable :: SingI s => Refuted (Refuted (Knockable s)) -> Knockable s
^^^^^^^^^^^
So, this
refuteRefuteKnockable rrK =
case isKnockable $ sing of
Proved k -> k
^^^
must have type Knockable s. Hence, the type of Proved k is inferred, probably containing s as well. That is the same type of isKnockable $ sing, from which we infer what type should be applied to sing (exploiting the signature of isKnockable). GHC does all of this for us.
In the latter example, we can't perform the same reasoning.
case sing of
SOpened -> OrRight $ Refl
SClosed -> OrLeft KnockClosed
SLocked -> OrLeft KnockLocked
is ambiguous because, even if the three branches must return a known type, we can still call sing on a different type then s and make everything typecheck. Since there isn't a unique s, inference can not work.
Note that above I had to guess a few things. If you shared the definitions of your types, we could be more accurate. (I.e., where is SOpened defined? What about Knockable, etc.?)

How do I get 'unpredictable' overloading on a return type working in Haskell?

I have some type instances. Let's call them A, B, and C. They all are instances of typeclass X. Now I would like to create a seperate function create that creates an instance of A, B or C given some input (let's say a string). The type system cannot know what input is going to give what type. That's the thing Haskell doesn't like, and I think I know the answer, but I want to be sure. The current error I'm getting is:
• Couldn't match expected type ‘c’ with actual type ‘GCCCommand’
‘c’ is a rigid type variable bound by
the type signature for:
compiler :: forall c. CompilerCommand c => String -> c
at src/System/Command/Typed/CC.hs:29:1-44
• In the expression: gcc path
In an equation for ‘compiler’:
compiler path
| exe == "g++" || exe == "gcc" || exe == "cc" || exe == "cpp"
= gcc path
where
exe = takeFileName path
• Relevant bindings include
compiler :: String -> c
(bound at src/System/Command/Typed/CC.hs:31:1)
Does that mean, as I suspect, that it is not possible to overload on return type in this particular case because the compiler can't know upfront how the data will look in memory? How would you go to implement this function? I was thinking about creating something like the following:
data SuperX = SuperA A | SuperB B | SuperC C
create :: String -> SuperX
-- create can now be implemented
instance X SuperX where
-- a lot of boilerplate code ...
However, the boilerplate code suggests that it can be done better. Is this really the best way for doing it?
It depends what you need to do with it.
If your later processing doesn't care if it gets an A, a B, or C, just that it gets something that implements X...
restOfProgram :: X a => a -> ThingIWantToCompute
Then you could use continuation passing:
parseABC :: (X a => a -> r) -> String -> Maybe r
parseABC f "A" = Just (f A)
parseABC f ('B':xs) = Just (f (B xs))
parseABC f ('C':xs) = Just (f (C (read xs)))
parseABC _ _ = Nothing
Or an existential data wrapper:
data SomeX where
SomeX :: X t => t -> SomeX
parseABC :: String -> Maybe SomeX
parseABC "A" = Just (SomeX A)
parseABC ('B':xs) = Just (SomeX (B xs))
parseABC ('C':xs) = Just (SomeX (C (read xs)))
parseABC _ _ = Nothing
restOfProgram' :: SomeX -> ThingIWantToCompute
restOfProgram' (SomeX t) = restOfProgram t
If the later processing has different paths for A, B or C, you probably want to return a sum type like SuperX.

How to write getters for existential types in Haskell

Thanks to the answer to this question I've defined a type like so:
data Chain = forall a. Integral a => Chain [[a]] [a] a a
I need to write a getter function for each field, or argument if you like. Here's my first attempt:
getSimplices (Chain simplices _ _ _) = simplices
But when I try to compile ghc gives the following error:
Chain.hs:10:40: error:
• Couldn't match expected type ‘t’ with actual type ‘[[a]]’
because type variable ‘a’ would escape its scope
This (rigid, skolem) type variable is bound by
a pattern with constructor:
Chain :: forall a. Integral a => [[a]] -> [a] -> a -> a -> Chain,
in an equation for ‘getSimplices’
at Chain.hs:10:15-35
• In the expression: simplices
In an equation for ‘getSimplices’:
getSimplices (Chain simplices _ _ _) = simplices
• Relevant bindings include
simplices :: [[a]] (bound at Chain.hs:10:21)
getSimplices :: Chain -> t (bound at Chain.hs:10:1)
I fixed it like this:
getSimplices (Chain simplices _ _ _) = map (map fromIntegral) simplices
Even if some kind of ghc magic prevents this from being obscenely slow for a getter, I think fixing something this way is just atrocious. Is there a better way to define getters for types like this?
The constructor of an existential type necessarily "forgets" about a:
Chain :: Integral a => [[a]] -> [[a]] -> a -> a -> Chain
Note how the resulting type no longer depends on a.
A consequence of this is that, when we pattern match on Chain, we can not make any assumption about what a is. After all we could have chosen anything when constructing. The only knowledge we have on a is that it must be an integral type. Hence, we can only access using the methods of the Integral type class.
The general rule is that, when we pattern match on Chain, we must return a value of a type which does not depend on a. A getter like
getter (Chain _ _ x _) = x
violate that rule. After all, what type would that have?
getter :: Chain -> ???
Surely not
getter :: Chain -> a
which would instead mean that we can extract any type we wish from Chain. This can not realistically work: we can't be free to choose what type to put in, and then be also free to choose what type to take out.
What we can do, however, is to exploit Integral:
getter :: Chain -> Integer
getter (Chain _ _ x _) = fromIntegral x
Integer does not depend on a, so it is OK.
What type do you suppose getSimplices should have? The "obvious" choice is
getSimplices :: Integral a => Chain -> [[a]]
But this doesn't work with your implementation, because the caller of getSimplices gets to choose the a, and there's no guarantee that the values stored in the Chain are of the same type that the caller wants, since you threw that information away. Consider:
let c = Chain [[1 :: Int]] [2] 3 4
in (getSimplices c) :: [[Integer]]
This is clearly allowed by your two type signatures which promise to work for any Integral type, but also clearly cannot work without some conversion: the Ints have to be turned into Integers somehow.
As the comments say, this is rather unusual. It would be much simpler to add a type parameter to Chain, so that it tracks the type you used to create it, and constrains its output to that type as well:
data Chain a = Chain [[a]] [a] a a
getSimplices :: Chain a -> [[a]]
getSimplices (Chain xs _ _ _) = xs

Basic Haskell function types?

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

Haskell type declarations

In Haskell, why does this compile:
splice :: String -> String -> String
splice a b = a ++ b
main = print (splice "hi" "ya")
but this does not:
splice :: (String a) => a -> a -> a
splice a b = a ++ b
main = print (splice "hi" "ya")
>> Type constructor `String' used as a class
I would have thought these were the same thing. Is there a way to use the second style, which avoids repeating the type name 3 times?
The => syntax in types is for typeclasses.
When you say f :: (Something a) => a, you aren't saying that a is a Something, you're saying that it is a type "in the group of" Something types.
For example, Num is a typeclass, which includes such types as Int and Float.
Still, there is no type Num, so I can't say
f :: Num -> Num
f x = x + 5
However, I could either say
f :: Int -> Int
f x = x + 5
or
f :: (Num a) => a -> a
f x = x + 5
Actually, it is possible:
Prelude> :set -XTypeFamilies
Prelude> let splice :: (a~String) => a->a->a; splice a b = a++b
Prelude> :t splice
splice :: String -> String -> String
This uses the equational constraint ~. But I'd avoid that, it's not really much shorter than simply writing String -> String -> String, rather harder to understand, and more difficult for the compiler to resolve.
Is there a way to use the second style, which avoids repeating the type name 3 times?
For simplifying type signatures, you may use type synonyms. For example you could write
type S = String
splice :: S -> S -> S
or something like
type BinOp a = a -> a -> a
splice :: BinOp String
however, for something as simple as String -> String -> String, I recommend just typing it out. Type synonyms should be used to make type signatures more readable, not less.
In this particular case, you could also generalize your type signature to
splice :: [a] -> [a] -> [a]
since it doesn't depend on the elements being characters at all.
Well... String is a type, and you were trying to use it as a class.
If you want an example of a polymorphic version of your splice function, try:
import Data.Monoid
splice :: Monoid a=> a -> a -> a
splice = mappend
EDIT: so the syntax here is that Uppercase words appearing left of => are type classes constraining variables that appear to the right of =>. All the Uppercase words to the right are names of types
You might find explanations in this Learn You a Haskell chapter handy.

Resources