Defaulting the following constraints to type 'Double' when using Scientific - haskell

I have two scientific numbers that are necessarily Integers that I want to convert to Ints, as below.
Please ignore code conventions and the idiomaticness of the code.
> import qualified Data.Vector as V
> import Data.Scientific
> cToTy (Array v) = case V.toList v of
> [String nm, Number p, Number s]
> | all (==True) $ map isInteger [p,s] -- We make sure they're always integers
> , [pr,sc] <- map (forceEitherToInt . floatingOrInteger) [p,s] -- And then hack them out
> forceEitherToInt :: (RealFloat r, Integral i) => Either r i -> Int
> forceEitherToInt (Left _a) = 0 -- This shouldn't happen, so we'll default it to 0 all the time.
> forceEitherToInt (Right a) = fromIntegral a
However, I get this warning and I can't figure out how to rid myself of them.
JsonUtils.lhs:76:26: Warning:
Defaulting the following constraint(s) to type ‘Double’
(RealFloat r0) arising from a use of ‘forceEitherToInt’
In the first argument of ‘(.)’, namely ‘forceEitherToInt’
In the first argument of ‘map’, namely
‘(forceEitherToInt . floatingOrInteger)’
In a stmt of a pattern guard for
a case alternative:
[pr, sc] <- map (forceEitherToInt . floatingOrInteger) [p, s]
Does anyone have any thoughts or ideas?

First off, you can explicitly cause an error if "neither should happen"; second, you can drop RealFloat as #bheklilr states; thirdly you can specify the double more concretely if you prefer the double; fourthly it can help with Hungarian notation if you write 'A from B' rather than 'B to A' in your names. So you could write for example:
intFromEither :: (Integral i) => Either Double i -> Int
intFromEither (Left d) = error $
"intFromEither tried to coerce `Left " ++ show d ++ "` to an Int."
intFromEither (Right i) = fromIntegral i
You can replace the Double above with x to make it more general; the most general type signature here is (Integral a, Num b) => Either t a -> b.

Related

Putting a type in the Read typeclass doesn't work in the REPL

I'm defining a type GosperInteger, representing the Eisenstein integers in a complex base, and I'd like to enter these numbers in the REPL and do operations on them. So I put the type in the Read and Show typeclasses. Here's the code (there's also an Internals module, see https://github.com/phma/gosperbase to run it):
module Data.GosperBase where
import Data.Array.Unboxed
import Data.Word
import Data.GosperBase.Internals
import qualified Data.Sequence as Seq
import Data.Sequence ((><), (<|), (|>), Seq((:<|)), Seq((:|>)))
import Data.Char
import Data.List
import Data.Maybe
{- This computes complex numbers in base 2.5-√(-3/4), called the Gosper base
because it is the scale factor from one Gosper island to the next bigger one.
The digits are cyclotomic:
2 3
6 0 1
4 5
For layout of all numbers up to 3 digits, see doc/GosperBase.ps .
-}
newtype GosperInteger = GosperInteger (Seq.Seq Word)
chunkDigitsInt :: Seq.Seq Char -> Maybe (Seq.Seq (Seq.Seq Char))
-- ^If the string ends in 'G', reverses the rest of the characters
-- and groups them into chunks of digitsPerLimb.
chunkDigitsInt (as:|>'G') = Just (Seq.reverse (Seq.chunksOf (fromIntegral digitsPerLimb) (Seq.reverse as)))
chunkDigitsInt as = Nothing
parseChunkRjust :: Seq.Seq Char -> Maybe Word
parseChunkRjust Seq.Empty = Just 0
parseChunkRjust (n:<|ns) =
let ms = parseChunkRjust ns
in case ms of
Just num -> if (n >= '0' && n < '7')
then Just (7 * num + fromIntegral (ord n - ord '0'))
else Nothing
Nothing -> Nothing
showLimb :: Word -> Word -> String
showLimb _ 0 = ""
showLimb val ndig = chr (fromIntegral ((val `div` 7 ^ (ndig-1)) `mod` 7) + ord '0') : (showLimb val (ndig-1))
parseRjust :: Seq.Seq Char -> Maybe (Seq.Seq Word)
parseRjust as =
let ns = chunkDigitsInt as
in case ns of
Just chunks -> traverse parseChunkRjust chunks
Nothing -> Nothing
showRjust' :: Seq.Seq Word -> String
showRjust' Seq.Empty = ""
showRjust' (a:<|as) = (showLimb a digitsPerLimb) ++ (showRjust' as)
showRjust :: Seq.Seq Word -> String
showRjust Seq.Empty = "0"
showRjust (a:<|as) = (showLimb a (snd (msdPosLimb a))) ++ (showRjust' as)
parse1InitTail :: (String, String) -> Maybe (GosperInteger, String)
parse1InitTail (a,b) =
let aParse = parseRjust (Seq.fromList a)
in case aParse of
Just mant -> Just (GosperInteger mant,b)
Nothing -> Nothing
parseGosperInteger :: String -> [(GosperInteger, String)]
parseGosperInteger str =
let its = zip (inits str) (tails str) -- TODO stop on invalid char
in catMaybes (fmap parse1InitTail its)
instance Read GosperInteger where
readsPrec _ str = parseGosperInteger str
instance Show GosperInteger where
show (GosperInteger m) = showRjust m ++ "G"
iAdd :: GosperInteger -> GosperInteger -> GosperInteger
iAdd (GosperInteger a) (GosperInteger b) =
GosperInteger (stripLeading0 (addRjust a b))
iMult :: GosperInteger -> GosperInteger -> GosperInteger
iMult (GosperInteger a) (GosperInteger b) =
GosperInteger (stripLeading0 (mulMant a b))
I'd like to do
> 425G * 256301G
16061525G
which requires putting GosperInteger in the Num typeclass, which I haven't done yet.
Showing a number works, and calling read on a string works, but reading a number typed into the REPL does not. Why?
> read "45G" :: GosperInteger
45G
> 45G
<interactive>:2:3: error: Data constructor not in scope: G
It is not possible to do that in a proper way (you can probably bodge this by writing an odd Num instance).
I think a better approach would be to just write that num instance, then you can write:
ghci> 425 * 256301 :: GosperInteger
16061525
If you don't want to have to write that :: GosperInteger signature you can do a few things:
Use ghci> default (GosperInteger, Double) that will mean it will automatically pick your GosperInteger type if there is ambiguity. You can also use this in normal source files.
Define a function g :: GosperInteger -> GosperInteger; g = id which you can use to disambiguate manually with less syntactic overhead:
ghci> g (425 * 256301)
16061525
The GHCi repl doesn't simply call read on the text that you type in. Instead, it has a much more complicated parser that separates your text into various tokens. One type of token is numeric: any integral number you type in will get "read" as an Integer. Of course, if you type 32 and want it to be an Int, not an Integer, this would be a problem, so the Num type class has a super convenient fromInteger function. With this, an Integer token can be converted into any instance of the Num class.
But, you want something slightly different: you want the parser to group together the numeric token along with the G token and treat them as one unit. For full support, you'd need to make an extension to the GHC parser, much like how if you type 2e7 into the prompt, you correctly get a floating point number. This isn't a simple change you can address in your source file or GHCi settings.
With all that said, there are some hacks we can play with. As Noughtmare mentions, "you can probably bodge this by writing an odd Num instance", and indeed you can! Fair warning: you probably don't want to do this, but let's explore it anyway.
The problem is that the parser returned two tokens, one that's numeric and the other that's G. Since it's uppercase, that G token is being interpreted as a data constructor (your error message pointed that out too: " Data constructor not in scope: G"). The key is to use this to our advantage.
Consider the following:
data G = G
deriving Show
instance Num (G -> GosperInteger) where
fromInteger i G = integerToGosperInteger i
Now, assuming you wrote that function integerToGosperInteger, this instance would let you type, e.g., 45G and produce a GosperInteger 45G. Hurrah! You can even do 425G * 256301G and it will work as expected. Furthermore, if you cleverly omit a fromInteger definition from your Num GosperInteger class, then you'll get a runtime error if you try to simply use a number like 425 as as GosperInteger (that is, you'll get an error for implicit coercions that don't have the G).
There are some problems.
If you try this, you'll find that type inference is pretty terrible. It probably won't work right at the prompt unless you set default (GosperInteger, Double), and you'll probably want to use lots of type annotations in your source files.
If you leave out the G, you'll get terrible type error messages or, even worse, runtime errors.
You'll get a warning that your Num instance for G -> GosperInteger is incomplete. It is incomplete, but there's no sensible definitions for anything else. You could suppress the warning or set all of the missing methods to error "This isn't how this is supposed to be used" or something, but it's still a bit of a blemish in the code.
But, if you can deal with the problems and you squint hard enough, it sorta kinda gets you what you want.

Why does ghc warn that ^2 requires "defaulting the constraint to type 'Integer'?

If I compile the following source file with ghc -Wall:
main = putStr . show $ squareOfSum 5
squareOfSum :: Integral a => a -> a
squareOfSum n = (^2) $ sum [1..n]
I get:
powerTypes.hs:4:18: warning: [-Wtype-defaults]
• Defaulting the following constraints to type ‘Integer’
(Integral b0) arising from a use of ‘^’ at powerTypes.hs:4:18-19
(Num b0) arising from the literal ‘2’ at powerTypes.hs:4:19
• In the expression: (^ 2)
In the expression: (^ 2) $ sum [1 .. n]
In an equation for ‘squareOfSum’:
squareOfSum n = (^ 2) $ sum [1 .. n]
|
4 | squareOfSum n = (^2) $ sum [1..n]
| ^^
I understand that the type of (^) is:
Prelude> :t (^)
(^) :: (Integral b, Num a) => a -> b -> a
which means it works for any a^b provided a is a Num and b is an Integral. I also understand the type hierarchy to be:
Num --> Integral --> Int or Integer
where --> denotes "includes" and the first two are typeclasses while the last two are types.
Why does ghc not conclusively infer that 2 is an Int, instead of "defaulting the constraints to Integer". Why is ghc defaulting anything? Is replacing 2 with 2 :: Int a good way to resolve this warning?
In Haskell, numeric literals have a polymorphic type
2 :: Num a => a
This means that the expression 2 can be used to generate a value in any numeric type. For instance, all these expression type-check:
2 :: Int
2 :: Integer
2 :: Float
2 :: Double
2 :: MyCustomTypeForWhichIDefinedANumInstance
Technically, each time we use 2 we would have to write 2 :: T to choose the actual numeric type T we want. Fortunately, this is often not needed since type inference can frequently deduce T from the context. E.g.,
foo :: Int -> Int
foo x = x + 2
Here, x is an Int because of the type annotation, and + requires both operands to have the same type, hence Haskell infers 2 :: Int. Technically, this is because (+) has type
(+) :: Num a => a -> a -> a
Sometimes, however, type inference can not deduce T from the context. Consider this example involving a custom type class:
class C a where bar :: a -> String
instance C Int where bar x = "Int: " ++ show x
instance C Integer where bar x = "Integer: " ++ show x
test :: String
test = bar 2
What is the value of test? Well, if 2 is an Int, then we have test = "Int: 2". If it is an Integer, then we have test = "Integer: 2". If it's another numeric type T, we can not find an instance for C T.
This code is inherently ambiguous. In such a case, Haskell mandates that numeric types that can not be deduced are defaulted to Integer (the programmer can change this default to another type, but it's not relevant now). Hence we have test = "Integer: 2".
While this mechanism makes our code type check, it might cause an unintended result: for all we know, the programmer might have wanted 2 :: Int instead. Because of this, GHC chooses the default, but warns about it.
In your code, (^) can work with any Integral type for the exponent. But, in principle, x ^ (2::Int) and x ^ (2::Integer) could lead to different results. We know this is not the case since we know the semantics of (^), but for the compiler (^) is only a random function with that type, which could behave differently on Int and Integer. Consider, e.g.,
a ^ n = if n + 3000000000 < 0 then 0 else 1
When n = 2, if we use n :: Int the if guard could be true on a 32 bit system. This is not the case when using n :: Integer which never overflows.
The standard solution, in these cases, is to resolve the warning using something like x ^ (2 :: Int).

How to solve this in Haskell?

I'm a beginner in Haskell and I would need help with this problem.
e :: [[(c,[d])]] -> Int
e [(x,xs):[y,ys]] = 0
The goal would be to define a term "z", that gives "e z == 0".
I just can't figure it out, any help would be appreciated.
Well, you have a clause right before you that will give 0 as the result, so all that's left to do is to generate a term matching it. Because patterns and expressions use essentially the same syntax, that's just a matter of taking the pattern
[(x,xs):[y,ys]]
and replacing all the variables with concrete values. In this case there's an extremely easy solution: note that the matched variables aren't even used, i.e. the clause could (and should!) have been written like this (I'm also regrouping to make the list syntax more consistent)
e [[(_,_),_,_]] = 0
Because of this, you could simply leave them all undefined:
Prelude> let e :: [[(c,[d])]] -> Int ; e [[(_,_),_,_]] = 0
Prelude> e [[(undefined, undefined), undefined, undefined]]
0
If you want something that feels less like a cheat, you need to pick concrete types for c and d. You can do that at will because they're unconstrained polymorphic type-variables; let's use c ~ Char and d ~ Bool. The most elegant way of picking concrete types is to use the type-applications extension
Prelude> :set -XTypeApplications
Prelude> :t e #Char #Bool
e #Char #Bool :: [[(Char, [Bool])]] -> Int
Then, you can ask the compiler what type each gap should be.
Prelude> e #Char #Bool [[(_,_),_,_]]
<interactive>:6:36: error:
• Found hole: _ :: Char
• In the expression: _
In the expression: (_, _)
In the expression: [(_, _), _, _]
• Relevant bindings include it :: Int (bound at <interactive>:6:1)
...
ok, let's put in some random character, how about 'q'
Prelude> e #Char #Bool [[('q',_),_,_]]
<interactive>:7:40: error:
• Found hole: _ :: [Bool]
• In the expression: _
In the expression: ('q', _)
In the expression: [('q', _), _, _]
• Relevant bindings include it :: Int (bound at <interactive>:7:1)
...
list of booleans, let's pick [True],
Prelude> e #Char #Bool [[('q',[True]),_,_]]
<interactive>:9:48: error:
• Found hole: _ :: (Char, [Bool])
...
and so on.
I have changed the function signature to make it possible to return x for showing purposes but the pattern is the same:
e :: Num a => [[(a,[a])]] -> a
e [(x,xs):[y,ys]] = x
The following term will match and return x which is zero.
λ> e [[(0, [1,2]), (3, [4,5]), (6, [7, 8])]]
0
Please note that the patterns are non-exhaustive meaning that if you give e anything with a different structure (not value), will result in an exception.
This pattern [(x,xs):[y,ys]] effectively means that you need to pass a list that has exactly 3 elements. If you look at this (x,xs):[y,ys], you see that it's a list of two elements with one to their left. That element to the left in turn is a tuple which is also destructured into its members and when you set the first member to zero, it return zero.
Alternatively, if you like to generally match on the given pattern and don't care to extract any elements, which was your original question, it becomes easier:
e' :: [[(c,[d])]] -> Int
e' [(x,xs):[y,ys]] = 0
Just pass in a list inside a list that has exactly 3 elements which are tuples as follows:
λ> e' [[(1,[]), (1,[]), (1,[])]]
0

Specify list type for input

I'm learning Haskell and I've decided to to the H-99 problem set. Naturally, I've become stuck on the first problem!
I have the following code:
module Main where
getLast [] = []
getLast x = x !! ((length x) - 1)
main = do
putStrLn "Enter a list:"
x <- readLn
print (getLast x)
Compiling this code gives the following error:
h-1.hs:8:14:
No instance for (Read a0) arising from a use of `readLn'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Read () -- Defined in `GHC.Read'
instance (Read a, Read b) => Read (a, b) -- Defined in `GHC.Read'
instance (Read a, Read b, Read c) => Read (a, b, c)
-- Defined in `GHC.Read'
...plus 25 others
In a stmt of a 'do' block: x <- readLn
In the expression:
do { putStrLn "Enter a list:";
x <- readLn;
print (getLast x) }
In an equation for `main':
main
= do { putStrLn "Enter a list:";
x <- readLn;
print (getLast x) }
h-1.hs:9:9:
No instance for (Show a0) arising from a use of `print'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Show Double -- Defined in `GHC.Float'
instance Show Float -- Defined in `GHC.Float'
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus 26 others
In a stmt of a 'do' block: print (getLast x)
In the expression:
do { putStrLn "Enter a list:";
x <- readLn;
print (getLast x) }
In an equation for `main':
main
= do { putStrLn "Enter a list:";
x <- readLn;
print (getLast x) }
That's a large error, but it seems to me that Haskell isn't sure what the input type will be. That's fine, and completely understandable. However, as this is supposed to work on a list of generics, I'm not sure how to specify that type. I tried this:
x :: [a] <- readLn
...as [a] is the type that Haskell returns for an empty list (found with :t []). This won't compile either.
As I'm a beginner, I know there's a lot I'm missing, but in a basic sense - how can I satisfy Haskell's type system with input code? I'm a Haskell beginner looking for a beginner answer, if that's at all possible. (Also, note that I know there's a better way to do this problem (reverse, head) but this is the way I came up with first, and I'd like to see if I can make it work.)
You can't hope to write something like this which will detect the type of x at run time -- what kind of thing you're reading must be known at compile time. That's why #Sibi's answer uses [Int]. If it can't be deduced, you get a compile time error.
If you want a polymorphic read, you have to construct your own parser which lists the readable types.
maybeDo :: (Monad m) => Maybe a -> (a -> m b) -> m b
maybeDo f Nothing = return ()
maybeDo f (Just x) = f x
main = do
str <- getLine
maybeDo (maybeRead str :: Maybe Int) $ \i ->
putStrLn $ "Got an Int: " ++ show i
maybeDo (maybeRead str :: Maybe String) $ \s ->
putStrLn $ "Got a String: " ++ show s
There are lots of ways to factor out this repetition, but at some point you'll have to list all the types you'll accept.
(An easy way to see the problem is to define a new type MyInt which has the same Read instance as Int -- then how do we know whether read "42" should return an Int or a MyInt?)
This should work:
getLast :: Num a => [a] -> a
getLast [] = 0
getLast x = x !! ((length x) - 1)
main = do
putStrLn "Enter a list:"
x <- readLn :: IO [Int]
print (getLast x)
why return 0 for an empty list, instead of an empty list?
Because it won't typecheck. Because you are returning [] for empty list and for other cases you are returning the element inside the list i.e a. Now since a type is not equal to list, it won't typecheck. A better design would be to catch this type of situation using the Maybe datatype.
Also, because of returning 0, the above function will work only for List of types which have Num instances created for them. You can alleviate that problem using error function.
However, this should work for a generic list, not just a list of Ints
or Numbers, right?
Yes, it should work for a polymorphic list. And you can create a function like getLast which will work for all type of List. But when you want to get input from the user, it should know what type of input you are giving. Because the typechecker won't be able to know whether you meant it as List of Int or List of Double or so on.

Haskell type error: Could not deduce (Show a) arising from a use of `show' from the context (Num a)

I am configuring xmonad, and since I have to start a couple of dzen instances, I decided that it could be better to use a function that takes the parameters for x and y position, width, height and text align:
-- mydzen.hs
import Data.List
-- | Return a string that launches dzen with the given configuration.
myDzen :: Num a => a -> a -> a -> Char -> String -> String
myDzen y x w ta e =
intercalate " "
[ "dzen2"
, "-x" , show x
, "-w" , show w
, "-y" , show y
, "-h" , myHeight
, "-fn" , quote myFont
, "-bg" , quote myDBGColor
, "-fg" , quote myFFGColor
, "-ta" , [ta]
, "-e" , quote e
]
quote :: String -> String
quote x = "'" x "'"
-- dummy values
myHeigth = "20"
myFont = "bitstream"
myDBGColor = "#ffffff"
myFFGColor = "#000000"
Could not deduce (Show a) arising from a use of `show'
from the context (Num a)
bound by the type signature for
myDzen :: Num a => a -> a -> a -> Char -> String -> String
at mydzen.hs:(5,1)-(17,13)
Possible fix:
add (Show a) to the context of
the type signature for
myDzen :: Num a => a -> a -> a -> Char -> String -> String
In the expression: show x
In the second argument of `intercalate', namely
`["dzen2", "-x", show x, "-w", ....]'
In the expression:
intercalate " " ["dzen2", "-x", show x, "-w", ....]
Obviously, deleting the signature, or changing Num a for Show a solves the issue, but I can't understand why. The 'arguments' x, w and y are supposed to be almost any kind of numbers (100, 550.2, 1366 * 0.7 ecc).
I'm new to haskell and until now I haven't been able to (clearly) understand the error or find what's wrong.
Previously, Show and Eq were superclasses of Num and the code would compile.
In the new GHC, from version 7.4, this has changed, now Num does not depend on Show and Eq, so you need to add them to signatures.
The reason is separation of concerns - there are numeric types with no sensible equality and show function (computable reals, rings of functions).
Not all numbers are showable (standard types like Int or Integer are, but you could have defined your own type; how would compiler know?) You’re using show x in your function — therefore, a must belong to Show typeclass. You can change your signature to myDzen :: (Num a, Show a) => a -> a -> a -> Char -> String -> String and get rid of the error.
show is not part of the Num type class — to be able to use it, you have to add Show constraint alongside the Num one:
myDzen :: (Num a, Show a) => a -> a -> a -> Char -> String -> String

Resources