Printer in Haskell for Subst in Data.Comp.Variables - haskell

I have a function which returns a Subst defined in this library:
http://hackage.haskell.org/package/compdata-0.1/docs/Data-Comp-Variables.html#t:Subst
I am trying to print the return value. The printer should show a mapping from variables to terms.
When I try to print the result, I get:
• No instance for (Show (Cxt NoHole CTypeF ()))
arising from a use of ‘print’
• In the expression: (print subst)
I think this means I must implement a printer. I know that when it's a user defined class, I can do 'deriving show'. Could someone point out how I should go about printing this?
Also, this is my CTypeF structure.
data CTypeF a
= CVarF Int
| CArrF a a
| CIntF
| CBoolF
deriving (Eq, Data, Functor, Foldable, Traversable, Show)
It derives show, so I don't think the issue is here.

Cxt has a Show instance, but it requires its f parameter to have an instance of ShowF.
(Functor f, ShowF f, Show a) => Show (Cxt h f a)
So you need to make CTypeF have an instance of ShowF. To do that, you can use makeShowF with Template Haskell.
$(makeShowF ''CTypeF)

Related

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.

What is the right way to typecheck dependent lambda abstraction using 'bound'?

I am implementing a simple dependently-typed language, similar to the one described by Lennart Augustsson, while also using bound to manage bindings.
When typechecking a dependent lambda term, such as λt:* . λx:t . x, I need to:
"Enter" the outer lambda binder, by instantiating t to something
Typecheck λx:t . x, yielding ∀x:t . t
Pi-abstract the t, yielding ∀t:* . ∀x:t . t
If lambda was non-dependent, I could get away with instantiating t with its type on step 1, since the type is all I need to know about the variable while typechecking on step 2.
But on step 3 I lack the information to decide which variables to abstract over.
I could introduce a fresh name supply and instantiate t with a Bound.Name.Name containing both the type and a unique name. But I thought that with bound I shouldn't need to generate fresh names.
Is there an alternative solution I'm missing?
We need some kind of context to keep track of the lambda arguments. However, we don't necessarily need to instantiate them, since bound gives us de Bruijn indices, and we can use those indices to index into the context.
Actually using the indices is a bit involved, though, because of the type-level machinery that reflects the size of the current scope (or in other words, the current depth in the expression) through the nesting of Var-s. It necessitates the use of polymorphic recursion or GADTs. It also prevents us from storing the context in a State monad (because the size and thus the type of the context changes as we recurse). I wonder though if we could use an indexed state monad; it'd be a fun experiment. But I digress.
The simplest solution is to represent the context as a function:
type TC a = Either String a -- our checker monad
type Cxt a = a -> TC (Type a) -- the context
The a input is essentially a de Bruijn index, and we look up a type by applying the function to the index. We can define the empty context the following way:
emptyCxt :: Cxt a
emptyCxt = const $ Left "variable not in scope"
And we can extend the context:
consCxt :: Type a -> Cxt a -> Cxt (Var () a)
consCxt ty cxt (B ()) = pure (F <$> ty)
consCxt ty cxt (F a) = (F <$>) <$> cxt a
The size of the context is encoded in the Var nesting. The increase in the size is apparent here in the return type.
Now we can write the type checker. The main point here is that we use fromScope and toScope to get under binders, and we carry along an appropriately extended Cxt (whose type lines up just perfectly).
data Term a
= Var a
| Star -- or alternatively, "Type", or "*"
| Lam (Type a) (Scope () Term a)
| Pi (Type a) (Scope () Term a)
| App (Type a) (Term a)
deriving (Show, Eq, Functor)
-- boilerplate omitted (Monad, Applicative, Eq1, Show1 instances)
-- reduce to normal form
rnf :: Term a -> Term a
rnf = ...
-- Note: IIRC "Simply easy" and Augustsson's post reduces to whnf
-- when type checking. I use here plain normal form, because it
-- simplifies the presentation a bit and it also works fine.
-- We rely on Bound's alpha equality here, and also on the fact
-- that we keep types in normal form, so there's no need for
-- additional reduction.
check :: Eq a => Cxt a -> Type a -> Term a -> TC ()
check cxt want t = do
have <- infer cxt t
when (want /= have) $ Left "type mismatch"
infer :: Eq a => Cxt a -> Term a -> TC (Type a)
infer cxt = \case
Var a -> cxt a
Star -> pure Star -- "Type : Type" system for simplicity
Lam ty t -> do
check cxt Star ty
let ty' = rnf ty
Pi ty' . toScope <$> infer (consCxt ty' cxt) (fromScope t)
Pi ty t -> do
check cxt Star ty
check (consCxt (rnf ty) cxt) Star (fromScope t)
pure Star
App f x ->
infer cxt f >>= \case
Pi ty t -> do
check cxt ty x
pure $ rnf (instantiate1 x t)
_ -> Left "can't apply non-function"
Here's the working code containing the above definitions. I hope I didn't mess it up too badly.

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.

Does exporting type constructors make a difference?

Let's say I have an internal data type, T a, that is used in the signature of exported functions:
module A (f, g) where
newtype T a = MkT { unT :: (Int, a) }
deriving (Functor, Show, Read) -- for internal use
f :: a -> IO (T a)
f a = fmap (\i -> T (i, a)) randomIO
g :: T a -> a
g = snd . unT
What is the effect of not exporting the type constructor T? Does it prevent consumers from meddling with values of type T a? In other words, is there a difference between the export list (f, g) and (f, g, T()) here?
Prevented
The first thing a consumer will see is that the type doesn't appear in Haddock documentation. In the documentation for f and g, the type Twill not be hyperlinked like an exported type. This may prevent a casual reader from discovering T's class instances.
More importantly, a consumer cannot doing anything with T at the type level. Anything that requires writing a type will be impossible. For instance, a consumer cannot write new class instances involving T, or include T in a type family. (I don't think there's a way around this...)
At the value level, however, the main limitation is that a consumer cannot write a type annotation including T:
> :t (f . read) :: Read b => String -> IO (A.T b)
<interactive>:1:39: Not in scope: type constructor or class `A.T'
Not prevented
The restriction on type signatures is not as significant a limitation as it appears. The compiler can still infer such a type:
> :t f . read
f . read :: Read b => String -> IO (A.T b)
Any value expression within the inferrable subset of Haskell may therefore be expressed regardless of the availability of the type constructor T. If, like me, you're addicted to ScopedTypeVariables and extensive annotations, you may be a little surprised by the definition of unT' below.
Furthermore, because typeclass instances have global scope, a consumer can use any available class functions without additional limitation. Depending on the classes involved, this may allow significant manipulation of values of the unexposed type. With classes like Functor, a consumer can also freely manipulate type parameters, because there's an available function of type T a -> T b.
In the example of T, deriving Show of course exposes the "internal" Int, and gives a consumer enough information to hackishly implement unT:
-- :: (Show a, Read a) => T a -> (Int, a)
unT' = (read . strip . show') `asTypeOf` (mkPair . g)
where
strip = reverse . drop 1 . reverse . drop 9
-- :: T a -> String
show' = show `asTypeOf` (mkString . g)
mkPair :: t -> (Int, t)
mkPair = undefined
mkString :: t -> String
mkString = undefined
> :t unT'
unT' :: (Show b, Read b) => A.T b -> (Int, b)
> x <- f "x"
> unT' x
(-29353, "x")
Implementing mkT' with the Read instance is left as an exercise.
Deriving something like Generic will completely explode any idea of containment, but you'd probably expect that.
Prevented?
In the corners of Haskell where type signatures are necessary or where asTypeOf-style tricks don't work, I guess not exporting the type constructor could actually prevent a consumer from doing something they could with the export list (f, g, T()).
Recommendation
Export all type constructors that are used in the type of any value you export. Here, go ahead and include T() in your export list. Leaving it out doesn't accomplish anything other than muddying the documentation. If you want to expose an purely abstract immutable type, use a newtype with a hidden constructor and no class instances.

Help interpreting overlapping instances error message

I'm stumped on this overlapping instances error message. Sorry this is a nontrivial project, but the error should be local to the type signatures.
First, I declare f to be of a certain type,
let f = undefined :: (CompNode Int)
Then, I try to call my function pshow :: PrettyShow a => a -> String on it. I get this error message.
> pshow f
<interactive>:1:1:
Overlapping instances for PrettyShow (CompNode Int)
arising from a use of `pshow'
Matching instances:
instance (G.Graph g, PrettyShow (G.Vertex g)) => PrettyShow g
-- Defined at Graph.hs:61:10-57
instance (PrettyShow a, Show a) => PrettyShow (CompNode a)
-- Defined at Interpreter.hs:61:10-58
The problem is that CompNode Int is not a graph, so I don't think the first matching instance should be triggering. (The second one is the one I want to execute.) Indeed, if I write a function that requires its argument to be a graph,
> :{
| let g :: G.Graph a => a -> a
| g = id
| :}
and then call it on f, I get the expected no instance error message,
> g f
<interactive>:1:1:
No instance for (G.Graph (CompNode Int))
Thanks in advance, sorry to crowdsource. I'm using GHC 7.0.4.
The problem is that CompNode Int is not a graph, so I don't think the first matching instance should be triggering.
You would think that, but unfortunately it doesn't work that way.
When GHC is selecting an instance, it looks only at the head, i.e., the part after the class name. Only after instance selection is done does it examine the context, i.e., the part before the =>. Mismatches in the context can cause the instance to be rejected and result in a type-checking error, but they won't cause GHC to backtrack and look for another instance.
So, given these instances:
instance (G.Graph g, PrettyShow (G.Vertex g)) => PrettyShow g
instance (PrettyShow a, Show a) => PrettyShow (CompNode a)
...if we ignore the context, they look like this:
instance PrettyShow g
instance PrettyShow (CompNode a)
Which should make it clear that the first instance is completely general and overlaps absolutely everything.
In some cases you can use the OverlappingInstances extension, but that doesn't change the above behavior; rather, it lets GHC resolve ambiguous instances by picking the uniquely most-specific one, if such exists. But using overlapping instances can be tricky and lead to cryptic errors, so I'd encourage you to first rethink the design and see if you can avoid the issue entirely.
That said, in the particular example here, CompNode a is indeed an unambiguously more specific match for CompNode Int, so GHC would select it instead of the general instance.

Resources