Problems with printf and ambiguous type variables - haskell

I have a little ambiguous type variable problem. I love haskell but this is really what I still fail to handle.
The problem is very easy and involves printf from Text.Printf. Since the problem is very general I'll just but in some sample code:
program = do
d <- addd 4 8
printf "%d" d
addd x y = return (x+y)
Of course printf is imported. The compiler then gives me an, obvious, ambiguous type variable error between Num and PrintfArg. I just don't know where to fit in the right type signature.

There are a few places you could put a type signature. Firstly, addd has most general type of (and the most general type is (almost always) what GHC infers when you leave off the signature):
addd :: (Monad m, Num a) => a -> a -> m a
You could restrict this to only work on a certain type by giving addd an explicit type signature, so that it isn't at all polymorphic in the arguments, e.g.:
addd :: Monad m => Int -> Int -> m Int
-- or,
addd :: Monad m => Integer -> Integer -> m Integer
Or, you could inform GHC of the input type when you call addd, e.g.:
d <- addd 4 (8 :: Integer)
and then the type inference will infer that 4 and d are both Integers.
Lastly, you can give d a type. Either when you use it (if you use d multiple times, you only need a single annotation), like so:
printf "%d" (d :: Integer)
Or when you set it (requires the GHC extension ScopedTypeVariables):
{-# LANGUAGE ScopedTypeVariables #-}
[...]
add = do
(d :: Integer) <- addd 4 8

I will try to explain what is wrong with your program.
Try giving explicit type signature, it helps compiler to infer types and also you to understand your program better.
addd is a pure function so don't use return.
return in not what you expect coming from an imperative background.
why do you need printf after all, use print or putStrLn if you want to output to console. Use show if you want to convert a type (whose show instance is defined) to string.
Here is your corrected program anyways
import Text.Printf
program :: String
program = do
let d = addd 4 8
printf "%d" d
addd :: Int -> Int -> Int
addd x y = x+y
You can write it just using print as
program :: IO ()
program = do
print $ addd 4 8
addd :: Int -> Int -> Int
addd x y = x+y
Try reading some introductory material on Haskell

Related

Moving between instances of class like Num

The following might contain a stupid question but since I am somewhat new to Haskell I think I am in the clear. :)
I haven't got the faintest of how to express my question in valid Haskell lingo, but I think I can express it in English!
I my current state of naivety I believe there is some secret recipe that allows you to move between instance of a class, like instance of Num..
For example:
class Language l where
add :: Int -> Int -> l
jmp :: Int -> l
noop :: l
data Assembler where
Add :: Int -> Int -> Assembler
Jmp :: Int -> Assembler
Noop :: Assembler
instance Language Assembler where
add = Add
jmp = Jmp
noop = Noop
data C where
Plus :: Int -> Int -> C
Goto :: Int -> C
Void0 :: C
instance Language C where
add = Plus
jmp = Goto
noop = Void0
example :: C
example = add 1 2
Without changing the type of example how could I transform it to Assembler, I could write a function :: C -> Assembler, but that is not my question, rather I would like to ask if I could leverage the class/instance things instead to attain the same behaviour? Is there something here or I am I just buggering about?
When you talk about "some secret recipe that allows you to move between instance of a class, like instances of Num", you've perhaps gotten this impression by observing the behavior of numeric literals, and seeing that you can write:
> 2 :: Int
2
> 2 :: Integer
2
> 2 :: Double
2.0
> 2 :: Float
2.0
Here, it looks as if the integer 2 is allowed to "change types" between multiple instances of Num, right? So, why can't we do something similar with example?
> example :: C
Plus 1 2
> example :: Assembler
<interactive>:14:1: error:
• Couldn't match expected type ‘Assembler’ with actual type ‘C’
• In the expression: example :: Assembler
In an equation for ‘it’: it = example :: Assembler
Well, the reason has to do with the actual type of numeric literals. If we ask GHCi for the type of 2:
> :t 2
2 :: Num p => p
we see that the expression 2 doesn't actually have a specific (i.e., "monomorphic") integer type. Instead, 2 has a polymorphic type, Num p => p which can be thought of as "any type you like, as long as it has a Num instance". So, it's not that 2 is "changing types" in the above example. Rather, the type of 2 is being specialized from the polymorphic type Num p => p to a specific monomorphic type like Int or Double, depending on where it's used, in much the same way that the addition operator + can be specialized from its polymorphic type of:
(+) :: Num a => a -> a -> a
to any of:
(+) :: Int -> Int -> Int
(+) :: Double -> Double -> Double
etc.
when it's used in different contexts.
Getting back to your example, I think you were pretty quick to dismiss #boran's comment as some dirty trick that missed the point of your question. But, in fact, his comment is the answer to your question. The sort of "movement between instances of a class" that you're thinking of is accomplished by defining polymorphic expressions with type class constraints and then specializing to the desired instance.
Just as 2 :: Num p => p can be specialized to any Num instance, the polymorphic version of example':
example' :: Language l => l
example' = add 1 2
can be specialized to any Language instance:
> example' :: C
Plus 1 2
it :: C
> example' :: Assembler
Add 1 2
it :: Assembler
There's a whole paper about writing "tagless final" interpreters using this technique, and it's definitely worth reading.
Anyway, it's this specialization process that provides apparent movement between class instances. There's no other general, automatic mechanism for converting between arbitrary type class instances.

Function with type a -> b in Haskell?

Is there any kind of function in Haskell that has type a -> b? That means, is it possible to write a function such that f :: a -> b? I don't think a function like that exists for the following reason: suppose that we found f where f :: a -> b, what would f 2 produce? a value of type b, but what is b since Haskell cannot infere (I think) it from the arguments I gave? Is this correct? Otherwise, can you give me an example of such a function?
Barring ⊥ (bottom value – undefined etc.), which is always possible but never useful, there can indeed be no such function. This is one of the simplest instances of the so-called free theorems that we get from polymorphic type signatures.
You're on the right track with your intuitive explanation of why this is not possible, though it went off in the end. Yes, you can consider f (5 :: Int). The problem is not that the compiler “can't infer” what b would be – that would be the case for many realistic functions, e.g.
fromIntegral :: (Num b, Integral a) => a -> b
makes perfect sense; b will be inferred from the environment in which fromIntegral x is used. For instance, I might write†
average :: [Double] -> Double
average l = sum l / fromIntegral (length l)
In this case, length l :: a has the fixed type Int and fromIntegral (length l) :: b must have the fixed type Double to fit in the environment, and unlike in most other languages with type inference, information from the environment is available hereto in a Hindley-Milner based language.
No, the problem with f :: a -> b is that you could instantiate a and b to any ridiculous combination of types, not just different number types. Because f is unconstrainedly polymorphic, it would have to be able to convert any type into any other type.
In particular, it would be able to convert into the vacuous type Void.
evil :: Int -> Void
evil = f
And then I could have
muahar :: Void
muahar = f 0
But, by construction of Void, there cannot be a value of this type (save for ⊥ which you can't evaluate without either crashing or looping infinitely).
†It should be noted that this is by some standards not a very good way of computing the average.
In order to implement f :: a -> b, it means that f has to be able to return any possible type. Even types that don't exist today, but somebody could define in ten years' time. Without some kind of reflection feature, that's obviously impossible.
Well... "impossible" is a big word... As the other answers point out, it's impossible excluding bottom. In other words, f can never return a value of type b. It can throw an exception, or loop forever. But (arguably) neither of those things is really "returning a value".
f1 :: a -> b
f1 = error "f1"
f2 :: a -> b
f2 s = error "f2"
f3 :: a -> b
f3 x = f3 x
These functions are all subtly different, and they all compile just fine. And, of course, they're all useless! So yes, there is no useful function with type a -> b.
If you want to split hairs:
f1 throws an exception.
f1 'x' throws an exception.
f2 is a normal-looking function.
f2 'x' throws an exception.
f3 is a normal-looking function.
f3 'x' doesn't throw an exception, but it loops forever, so it never actually returns anything.
Basically any function you see that returns "any type" is a function that never actually returns. We can see this in unusual monads. For example:
f4 :: a -> Maybe b
It is perfectly possible to implement this function without throwing an exception or looping forever.
f4 x = Nothing
Again, we're not actually returning a b. We could similarly do
f5 :: a -> [b]
f5 x = []
f6 :: a -> Either String b
f6 x = Left "Not here"
f7 :: a -> Parser b
f7 x = fail "Not here"
There is, I think, exactly one, but it is cheating a little bit:
> let f _ = undefined
> :t f
f:: t -> t1
This only exists because bottom is considered a value of every type.
... but what is b since Haskell cannot infer it from the arguments I gave?
Depending on the context, Haskell can infer the return type; say:
{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances, FlexibleInstances #-}
class Cast a b where
cast :: a -> b
instance Cast a a where
cast = id
instance Cast Int String where
cast = show
instance Cast Int Double where
cast = fromIntegral
then,
cast :: Cast a b => a -> b
and if given enough context, Haskell knows which function to use:
\> let a = 42 :: Int
\> let b = 100.0 :: Double
\> "string: " ++ cast a -- Int -> String
"string: 42"
\> b * cast a -- Int -> Double
4200.0

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.

Haskell get type of algebraic parameter

I have a type
class IntegerAsType a where
value :: a -> Integer
data T5
instance IntegerAsType T5 where value _ = 5
newtype (IntegerAsType q) => Zq q = Zq Integer deriving (Eq)
newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]
I'm trying to make a nice "show" for the PolyRing type. In particular, I want the "show" to print out the type 'a'. Is there a function that returns the type of an algebraic parameter (a 'show' for types)?
The other way I'm trying to do it is using pattern matching, but I'm running into problems with built-in types and the algebraic type.
I want a different result for each of Integer, Int and Zq q.
(toy example:)
test :: (Num a, IntegerAsType q) => a -> a
(Int x) = x+1
(Integer x) = x+2
(Zq x) = x+3
There are at least two different problems here.
1) Int and Integer are not data constructors for the 'Int' and 'Integer' types. Are there data constructors for these types/how do I pattern match with them?
2) Although not shown in my code, Zq IS an instance of Num. The problem I'm getting is:
Ambiguous constraint `IntegerAsType q'
At least one of the forall'd type variables mentioned by the constraint
must be reachable from the type after the '=>'
In the type signature for `test':
test :: (Num a, IntegerAsType q) => a -> a
I kind of see why it is complaining, but I don't know how to get around that.
Thanks
EDIT:
A better example of what I'm trying to do with the test function:
test :: (Num a) => a -> a
test (Integer x) = x+2
test (Int x) = x+1
test (Zq x) = x
Even if we ignore the fact that I can't construct Integers and Ints this way (still want to know how!) this 'test' doesn't compile because:
Could not deduce (a ~ Zq t0) from the context (Num a)
My next try at this function was with the type signature:
test :: (Num a, IntegerAsType q) => a -> a
which leads to the new error
Ambiguous constraint `IntegerAsType q'
At least one of the forall'd type variables mentioned by the constraint
must be reachable from the type after the '=>'
I hope that makes my question a little clearer....
I'm not sure what you're driving at with that test function, but you can do something like this if you like:
{-# LANGUAGE ScopedTypeVariables #-}
class NamedType a where
name :: a -> String
instance NamedType Int where
name _ = "Int"
instance NamedType Integer where
name _ = "Integer"
instance NamedType q => NamedType (Zq q) where
name _ = "Zq (" ++ name (undefined :: q) ++ ")"
I would not be doing my Stack Overflow duty if I did not follow up this answer with a warning: what you are asking for is very, very strange. You are probably doing something in a very unidiomatic way, and will be fighting the language the whole way. I strongly recommend that your next question be a much broader design question, so that we can help guide you to a more idiomatic solution.
Edit
There is another half to your question, namely, how to write a test function that "pattern matches" on the input to check whether it's an Int, an Integer, a Zq type, etc. You provide this suggestive code snippet:
test :: (Num a) => a -> a
test (Integer x) = x+2
test (Int x) = x+1
test (Zq x) = x
There are a couple of things to clear up here.
Haskell has three levels of objects: the value level, the type level, and the kind level. Some examples of things at the value level include "Hello, world!", 42, the function \a -> a, or fix (\xs -> 0:1:zipWith (+) xs (tail xs)). Some examples of things at the type level include Bool, Int, Maybe, Maybe Int, and Monad m => m (). Some examples of things at the kind level include * and (* -> *) -> *.
The levels are in order; value level objects are classified by type level objects, and type level objects are classified by kind level objects. We write the classification relationship using ::, so for example, 32 :: Int or "Hello, world!" :: [Char]. (The kind level isn't too interesting for this discussion, but * classifies types, and arrow kinds classify type constructors. For example, Int :: * and [Int] :: *, but [] :: * -> *.)
Now, one of the most basic properties of Haskell is that each level is completely isolated. You will never see a string like "Hello, world!" in a type; similarly, value-level objects don't pass around or operate on types. Moreover, there are separate namespaces for values and types. Take the example of Maybe:
data Maybe a = Nothing | Just a
This declaration creates a new name Maybe :: * -> * at the type level, and two new names Nothing :: Maybe a and Just :: a -> Maybe a at the value level. One common pattern is to use the same name for a type constructor and for its value constructor, if there's only one; for example, you might see
newtype Wrapped a = Wrapped a
which declares a new name Wrapped :: * -> * at the type level, and simultaneously declares a distinct name Wrapped :: a -> Wrapped a at the value level. Some particularly common (and confusing examples) include (), which is both a value-level object (of type ()) and a type-level object (of kind *), and [], which is both a value-level object (of type [a]) and a type-level object (of kind * -> *). Note that the fact that the value-level and type-level objects happen to be spelled the same in your source is just a coincidence! If you wanted to confuse your readers, you could perfectly well write
newtype Huey a = Louie a
newtype Louie a = Dewey a
newtype Dewey a = Huey a
where none of these three declarations are related to each other at all!
Now, we can finally tackle what goes wrong with test above: Integer and Int are not value constructors, so they can't be used in patterns. Remember -- the value level and type level are isolated, so you can't put type names in value definitions! By now, you might wish you had written test' instead:
test' :: Num a => a -> a
test' (x :: Integer) = x + 2
test' (x :: Int) = x + 1
test' (Zq x :: Zq a) = x
...but alas, it doesn't quite work like that. Value-level things aren't allowed to depend on type-level things. What you can do is to write separate functions at each of the Int, Integer, and Zq a types:
testInteger :: Integer -> Integer
testInteger x = x + 2
testInt :: Int -> Int
testInt x = x + 1
testZq :: Num a => Zq a -> Zq a
testZq (Zq x) = Zq x
Then we can call the appropriate one of these functions when we want to do a test. Since we're in a statically-typed language, exactly one of these functions is going to be applicable to any particular variable.
Now, it's a bit onerous to remember to call the right function, so Haskell offers a slight convenience: you can let the compiler choose one of these functions for you at compile time. This mechanism is the big idea behind classes. It looks like this:
class Testable a where test :: a -> a
instance Testable Integer where test = testInteger
instance Testable Int where test = testInt
instance Num a => Testable (Zq a) where test = testZq
Now, it looks like there's a single function called test which can handle any of Int, Integer, or numeric Zq's -- but in fact there are three functions, and the compiler is transparently choosing one for you. And that's an important insight. The type of test:
test :: Testable a => a -> a
...looks at first blush like it is a function that takes a value that could be any Testable type. But in fact, it's a function that can be specialized to any Testable type -- and then only takes values of that type! This difference explains yet another reason the original test function didn't work. You can't have multiple patterns with variables at different types, because the function only ever works on a single type at a time.
The ideas behind the classes NamedType and Testable above can be generalized a bit; if you do, you get the Typeable class suggested by hammar above.
I think now I've rambled more than enough, and likely confused more things than I've clarified, but leave me a comment saying which parts were unclear, and I'll do my best.
Is there a function that returns the type of an algebraic parameter (a 'show' for types)?
I think Data.Typeable may be what you're looking for.
Prelude> :m + Data.Typeable
Prelude Data.Typeable> typeOf (1 :: Int)
Int
Prelude Data.Typeable> typeOf (1 :: Integer)
Integer
Note that this will not work on any type, just those which have a Typeable instance.
Using the extension DeriveDataTypeable, you can have the compiler automatically derive these for your own types:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Typeable
data Foo = Bar
deriving Typeable
*Main> typeOf Bar
Main.Foo
I didn't quite get what you're trying to do in the second half of your question, but hopefully this should be of some help.

How to declare function (type misunderstanding Maybe)

I need a function which works like:
some :: (Int, Maybe Int) -> Int
some a b
| b == Nothing = 0
| otherwise = a + b
Use cases:
some (2,Just 1)
some (3,Nothing)
map some [(2, Just 1), (3,Nothing)]
But my code raise the error:
The equation(s) for `some' have two arguments,
but its type `(Int, Maybe Int) -> Int' has only one
I don't understand it.
Thanks in advance.
When you write
foo x y = ...
That is notation for a curried function, with a type like:
foo :: a -> b -> c
You have declared your function to expect a tuple, so you must write it:
some :: (Int, Maybe Int) -> Int
some (x, y) = ...
But Haskell convention is usually to take arguments in the former curried form. Seeing funcitons take tuples as arguments is very rare.
For the other part of your question, you probably want to express it with pattern matching. You could say:
foo :: Maybe Int -> Int
foo Nothing = 0
foo (Just x) = x + 1
Generalizing that to the OP's question is left as an exercise for the reader.
Your error doesn't come from a misunderstanding of Maybe: The type signature of some indicates that it takes a pair (Int, Maybe Int), while in your definition you provide it two arguments. The definition should thus begin with some (a,b) to match the type signature.
One way to fix the problem (which is also a bit more idiomatic and uses pattern matching) is:
some :: (Int, Maybe Int) -> Int
some (a, Nothing) = a
some (a, Just b) = a + b
It's also worth noting that unless you have a really good reason for using a tuple as input, you should probably not do so. If your signature were instead some :: Int -> Maybe Int -> Int, you'd have a function of two arguments, which can be curried. Then you'd write something like
some :: Int -> Maybe Int -> Int
some a Nothing = a
some a (Just b) = a + b
Also, you might want to add the following immediate generalization: All Num types are additive, so you might aswell do
some :: (Num n) => n -> Maybe n -> n
some a Nothing = a
some a (Just b) = a + b
(I've violated the common practice of using a, b, c... for type variables so as not to confuse the OP since he binds a and b to the arguments of some).

Resources