In GHCi, why can't I show `pure 1` in REPL? - haskell

I tried to assign a lifted value to a.
λ> :m Control.Applicative
λ> let a = pure 1
When I evaluated a in REPL, it prints 1.
λ> a
1
Therefore, I thought there may be an implementation of show for a, and tried this:
λ> show a
But the GHCi throws an error:
<interactive>:70:1-4:
No instance for (Show (f0 a0)) arising from a use of ‘show’
The type variables ‘f0’, ‘a0’ are ambiguous
Note: there are several potential instances:
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance (Show a, Show b) => Show (a, b) -- Defined in ‘GHC.Show’
instance (Show a, Show b, Show c) => Show (a, b, c)
-- Defined in ‘GHC.Show’
...plus 32 others
In the expression: show a
In an equation for ‘it’: it = show a
Does anyone have any ideas about this?

GHCi is defaulting the Applicative f => f to IO. When you do
λ> a
1
you actually run an IO Integer action such as
λ> let a = return 1
λ> a
1
GHCi by default prints the result of IO actions. Hence the 1 in the result line. (Quite confusingly, this 1 is not the value of a, nor the output of running a as an IO action -- just the returned value of the latter.)
GHCi uses a sophisticated heuristics to handle user input. First, it tries to show it, possibly defaulting some type classes like numeric ones. This fails in your case. When that fails, it tries to see if the input is an IO action. In such case, the action is run and, if the result can be showed, it is printed.
Note that this GHCi magic only happens at the top level.
When you try to show a, GHCi tries its magic on the whole show a, not on a, so the same effect does not happen.

Related

Show Constraint type in haskell

I am trying to use show function to print to the console value of zer or one, but I can not do it. Here is my code:
{-# LANGUAGE NoMonomorphismRestriction #-}
import Control.Arrow
import Data.List
import qualified Data.Map as M
import Data.Function
class Eq a => Bits a where
zer :: a
one :: a
instance Bits Int where
zer = 0
one = 1
instance Bits Bool where
zer = False
one = True
instance Bits Char where
zer = '0'
one = '1'
I am trying to use function show to convert zer or one to the string.
So I tried it:
k = zer
show k
but I got this error
<interactive>:10:1: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘show’
prevents the constraint ‘(Show a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance (Show k, Show a) => Show (M.Map k a)
-- Defined in ‘containers-0.5.7.1:Data.Map.Base’
instance Show Ordering -- Defined in ‘GHC.Show’
instance Show Integer -- Defined in ‘GHC.Show’
...plus 24 others
...plus 11 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the expression: show zer
In an equation for ‘it’: it = show zer
so i tried to create instance for show. So I added this to my code:
instance (Show a) => Show (Bits a) where
show zer = "0"
show one = "1"
But I got another error
main.hs:25:28: error:
• Expected a type, but ‘Bits a’ has kind ‘Constraint’
• In the first argument of ‘Show’, namely ‘Bits a’
In the instance declaration for ‘Show (Bits a)’
Can you tell me what I am doing wrong?
You're trying to make a class an instance of a class, rather than making a type an instance of a class. Compare:
Show a => Show (Bits a) -- Invalid
to
Show a => Show (Maybe a) -- Valid
where Maybe is a datatype whereas Bits is a class name.
I don't think it's possible to express "anything that has a Bits instance has a Show instance", because it can lead to overlapping instances: if you could define something like that, then when you use show :: Int -> String the compiler wouldn't know whether to use the Prelude's instance of Show Int or the show that would be defined by Int being an instance of Bits.
A messy workaround could be to enforce "the other direction": that every instance of Bits must be an instance of Show, which would allow you to use a's Show instance rather than your own one:
class (Show a, Eq a) => Bits a where
zer :: a
one :: a
main = print (zer :: Int)
although this requires an explicit type signature to resolve the ambiguity in the type of zer at the call site.

Default to a typeclass when a data type does not instantiate it [duplicate]

What I'd like to achieve is that any instance of the following class (SampleSpace) should automatically be an instance of Show, because SampleSpace contains the whole interface necessary to create a String representation and hence all possible instances of the class would be virtually identical.
{-# LANGUAGE FlexibleInstances #-}
import Data.Ratio (Rational)
class SampleSpace space where
events :: Ord a => space a -> [a]
member :: Ord a => a -> space a -> Bool
probability :: Ord a => a -> space a -> Rational
instance (Ord a, Show a, SampleSpace s) => Show (s a) where
show s = showLines $ events s
where
showLines [] = ""
showLines (e:es) = show e ++ ": " ++ (show $ probability e s)
++ "\n" ++ showLines es
Since, as I found out already, while matching instance declarations GHC only looks at the head, and not at contraints, and so it believes Show (s a) is about Rational as well:
[1 of 1] Compiling Helpers.Probability ( Helpers/Probability.hs, interpreted )
Helpers/Probability.hs:21:49:
Overlapping instances for Show Rational
arising from a use of ‘show’
Matching instances:
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance (Ord a, Show a, SampleSpace s) => Show (s a)
-- Defined at Helpers/Probability.hs:17:10
In the expression: show
In the first argument of ‘(++)’, namely ‘(show $ probability e s)’
In the second argument of ‘(++)’, namely
‘(show $ probability e s) ++ "" ++ showLines es
Question: is it possible (otherwise than by enabling overlapping instances) to make any instance of a typeclass automatically an instance of another too?
tl;dr: don't do that, or, if you insist, use -XOverlappingInstances.
This is not what the Show class is there for. Show is for simply showing plain data, in a way that is actually Haskell code and can be used as such again, yielding the original value.
SampleSpace should perhaps not be a class in the first place. It seems to be basically the class of types that have something like Map a Rational associated with them. Why not just use that as a field in a plain data type?
Even if we accept the design... such a generic Show instance (or, indeed, generic instance for any single-parameter class) runs into problems when someone makes another instance for a concrete type – in the case of Show, there are of course already plenty of instances around. Then how should the compiler decide which of the two instances to use? GHC can do it, in fact: if you turn on the -XOverlappingInstances extension, it will select the more specific one (i.e. instance SampleSpace s => Show (s a) is “overridden” by any more specific instance), but really this isn't as trivial as may seem – what if somebody defined another such generic instance? Crucial to recall: Haskell type classes are always open, i.e. basically the compiler has to assume that all types could possibly in any class. Only when a specific instance is invoke will it actually need the proof for that, but it can never proove that a type isn't in some class.
What I'd recommend instead – since that Show instance doesn't merely show data, it should be made a different function. Either
showDistribution :: (SampleSpace s, Show a, Ord a) => s a -> String
or indeed
showDistribution :: (Show a, Ord a) => SampleSpace a -> String
where SampleSpace is a single concrete type, instead of a class.

Show list of unknown type in Haskell

I was given an assignment in which I should have the type signature
Group g => Int -> Int -> [[g]]
However if g is ambiguous how can I print it? I get this error:
No instance for (Show g0) arising from a use of ‘print’
The type variable ‘g0’ is ambiguous
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 24 others
In the expression: print
In the expression: print $ myTest 10 0
In an equation for ‘main’: main = print $ myTest 10 0
Which makes sense to me. Is there an error in the assignment? Or is there a way to print an ambiguous type?
Try running
> :info Group
This should print out the Group typeclass and its members, followed by a list of instances. Pick one of these instances, then execute
> myTest 1 2 :: [[TheTypeYouPicked]]
If you wanted to use it inside main you'll have to give it a type signature there too:
main :: IO ()
main = print (myTest 10 0 :: [[TheTypeYouPicked]])
The reason why the compiler is showing you this error is because there could be many instances of Group to choose from, not all of them necessarily implement Show as well. In order to print something in the console, either by just executing it (there's an implicit print when you just run a normal function in GHCi) or with an explicit print it needs to implement Show.

Make a typeclass instance automatically an instance of another

What I'd like to achieve is that any instance of the following class (SampleSpace) should automatically be an instance of Show, because SampleSpace contains the whole interface necessary to create a String representation and hence all possible instances of the class would be virtually identical.
{-# LANGUAGE FlexibleInstances #-}
import Data.Ratio (Rational)
class SampleSpace space where
events :: Ord a => space a -> [a]
member :: Ord a => a -> space a -> Bool
probability :: Ord a => a -> space a -> Rational
instance (Ord a, Show a, SampleSpace s) => Show (s a) where
show s = showLines $ events s
where
showLines [] = ""
showLines (e:es) = show e ++ ": " ++ (show $ probability e s)
++ "\n" ++ showLines es
Since, as I found out already, while matching instance declarations GHC only looks at the head, and not at contraints, and so it believes Show (s a) is about Rational as well:
[1 of 1] Compiling Helpers.Probability ( Helpers/Probability.hs, interpreted )
Helpers/Probability.hs:21:49:
Overlapping instances for Show Rational
arising from a use of ‘show’
Matching instances:
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance (Ord a, Show a, SampleSpace s) => Show (s a)
-- Defined at Helpers/Probability.hs:17:10
In the expression: show
In the first argument of ‘(++)’, namely ‘(show $ probability e s)’
In the second argument of ‘(++)’, namely
‘(show $ probability e s) ++ "" ++ showLines es
Question: is it possible (otherwise than by enabling overlapping instances) to make any instance of a typeclass automatically an instance of another too?
tl;dr: don't do that, or, if you insist, use -XOverlappingInstances.
This is not what the Show class is there for. Show is for simply showing plain data, in a way that is actually Haskell code and can be used as such again, yielding the original value.
SampleSpace should perhaps not be a class in the first place. It seems to be basically the class of types that have something like Map a Rational associated with them. Why not just use that as a field in a plain data type?
Even if we accept the design... such a generic Show instance (or, indeed, generic instance for any single-parameter class) runs into problems when someone makes another instance for a concrete type – in the case of Show, there are of course already plenty of instances around. Then how should the compiler decide which of the two instances to use? GHC can do it, in fact: if you turn on the -XOverlappingInstances extension, it will select the more specific one (i.e. instance SampleSpace s => Show (s a) is “overridden” by any more specific instance), but really this isn't as trivial as may seem – what if somebody defined another such generic instance? Crucial to recall: Haskell type classes are always open, i.e. basically the compiler has to assume that all types could possibly in any class. Only when a specific instance is invoke will it actually need the proof for that, but it can never proove that a type isn't in some class.
What I'd recommend instead – since that Show instance doesn't merely show data, it should be made a different function. Either
showDistribution :: (SampleSpace s, Show a, Ord a) => s a -> String
or indeed
showDistribution :: (Show a, Ord a) => SampleSpace a -> String
where SampleSpace is a single concrete type, instead of a class.

Error while compiling print Either value

I'm trying to compile simple code snippet.
main = (putStrLn . show) (Right 3.423)
Compile results in the following error:
No instance for (Show a0) arising from a use of `show'
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 42 others
In the second argument of `(.)', namely `show'
In the expression: putStrLn . show
In the expression: (putStrLn . show) (Right 3.423)
When i execute same snippet from ghci everything works as expected.
Prelude> let main = (putStrLn . show) (Right 3.423)
Prelude> main
Right 3.423
So the question is what is going on?
The problem is that GHC can't determine what the full type of Right 3.423 is, it can only determine that it has the type Either a Double, and the instance of Show for Either looks like instance (Show a, Show b) => Show (Either a b). Without that extra constraint on Either a Double, GHC doesn't know how to print it.
The reason why it works in interactive mode is because of the dreaded monomorphism restriction, which makes GHCi more aggressive in the defaults it chooses. This can be disabled with :set -XNoMonomorphismRestriction, and that is going to become the default in future versions of GHC since it causes a lot of problems for beginners.
The solution to this problem is to put a type signature on Right 3.423 in your source code, like
main = (putStrLn . show) (Right 3.423 :: Either () Double)
Here I've just used () for a, since we don't care about it anyway and it's the "simplest" type that can be shown. You could put String or Int or Double or whatever you want there, so long as it implements Show.
A tip, putStrLn . show is exactly the definition of print, so you can just do
main = print (Right 3.423 :: Either () Double)
As #ØrjanJohansen points out, this is not the monomorphism restriction, but rather the ExtendedDefaultRules extension that GHCi uses, which essentially does exactly what I did above and shoves () into type variables to make things work in the interactive session.

Resources