Defining a function a -> String, which works for types without Show? - class

I'd like to define a function which can "show" values of any type, with special behavior for types which actually do define a Show instance:
magicShowCast :: ?
debugShow :: a -> String
debugShow x = case magicShowCast x of
Just x' -> show x'
Nothing -> "<unprintable>"
This would be used to add more detailed information to error messages when something goes wrong:
-- needs to work on non-Showable types
assertEq :: Eq a => a -> a -> IO ()
assertEq x y = when (x /= y)
(throwIO (AssertionFailed (debugShow x) (debugShow y)))
data CanShow = CanShow1
| CanShow 2
deriving (Eq, Show)
data NoShow = NoShow1
| NoShow2
deriving (Eq)
-- AssertionFailed "CanShow1" "CanShow2"
assertEq CanShow1 CanShow2
-- AssertionFailed "<unprintable>" "<unprintable>"
assertEq NoShow1 NoShow2
Is there any way to do this? I tried using various combinations of GADTs, existential types, and template haskell, but either these aren't enough or I can't figure out how to apply them properly.

The real answer: You can't. Haskell intentionally doesn't define a generic "serialize to string" function, and being able to do so without some type class constraint would violate parametricity all over town. Dreadful, just dreadful.
If you don't see why this poses a problem, consider the following type signature:
something :: (a, a) -> b -> a
How would you implement this function? The generic type means it has to be either const . fst or const . snd, right? Hmm.
something (x,y) z = if debugShow z == debugShow y then y else x
> something ('a', 'b') ()
'a'
> something ('a', 'b') 'b'
'b'
Oooooooops! So much for being able to reason about your program in any sane way. That's it, show's over, go home, it was fun while it lasted.
The terrible, no good, unwise answer: Sure, if you don't mind shamelessly cheating. Did I mention that example above was an actual GHCi session? Ha, ha.
import Control.Exception
import Control.Monad
import GHC.Vacuum
debugShow :: a -> String
debugShow = show . nameGraph . vacuumLazy
assertEq :: Eq a => a -> a -> IO ()
assertEq x y = when (x /= y) . throwIO . AssertionFailed $
unlines ["assertEq failed:", '\t':debugShow x, "=/=", '\t':debugShow y]
data NoShow = NoShow1
| NoShow2
deriving (Eq)
> assertEq NoShow1 NoShow2
*** Exception: assertEq failed:
[("|0",["NoShow1|1"]),("NoShow1|1",[])]
=/=
[("|0",["NoShow2|1"]),("NoShow2|1",[])]
Oh. Ok. That looks like a fantastic idea, doesn't it.
Anyway, this doesn't quite give you what you want, since there's no obvious way to fall back to a proper Show instance when available. On the other hand, this lets you do a lot more than show can do, so perhaps it's a wash.
Seriously, though. Don't do this in actual, working code. Ok, error reporting, debugging, logging... that makes sense. But otherwise, it's probably very ill-advised.

I asked this question a while ago on the haskell-cafe list, and the experts said no. Here are some good responses,
http://www.haskell.org/pipermail/haskell-cafe/2011-May/091744.html
http://www.haskell.org/pipermail/haskell-cafe/2011-May/091746.html
The second one mentions GHC advanced overlap, but my experience was that it doesn't really work.
For your particular problem, I'd introduce a typeclass
class MaybeShow a where mshow :: a -> String
make anything that is showable do the logical thing
instance Show a => MaybeShow a where mshow = show
and then, if you have a fixed number of types which wouldn't be showable, say
instance MaybeShow NotShowableA where mshow _ = "<unprintable>"
of course you could abstract it a little,
class NotShowable a
instance NotShowable a => MaybeShow a where mshow _ = "<unprintable>"
instance NotShowable NotShowableA -- etc.

You shouldn't be able to. The simplest way to implement type classes is by having them compile into an extra parameter
foo :: Show s => a -> s
turns into
foo :: show -> a -> s
The program just passess around the type class instances (like v-tables in C++) as ordinary data. This is why you can trivially use things that look not just like multiple dispatch in OO languages, but can dispatch off the return type.
The problem is that a signature
foo :: a -> String
has no way of getting the implementation of Show that goes for a in cases when it has one.
You might be able to get something like this to work in particular implementations, with the correct language extensions (overlapping instance, etc) on, but I havent tried it
class MyShow a where
myShow :: a -> String
instance (Show a) => MyShow a where
myShow = show
instance MyShow a where
myShow = ...
one trick that might help is enable type families. It can let you write code like
instance (a' ~ a, Show a') => MyShow a
which can sometimes help you get code past the compiler that it doesn't think looks okay.

Related

Why do `Left` and `Right` have two type parameters?

I understand it would be difficult to change now without breaking existing code, but I'm wondering why it was done that way in the first place.
Why not just:
sealed trait Either[+A, +B]
case class Left[A](x: A) extends Either[A, Nothing]
case class Right[B](x: B) extends Either[Nothing, B]
Is there some drawback here that I'm failing to see...?
Not sure how relevant this answer really is to Scala, but it certainly is in Haskell which is evidently where Scala's Either was borrowed from and so that's probably the best historical reason for why Scala did it this way.
Either is the canonical coproduct, i.e. for any types A and B you have
The type EitherA,B ≈ A ⊕ B
Two coprojections LeftA,B : A -> A⊕B and RightA,B : B -> A⊕B
such that for any type Y and any functions fA : A -> Y and fB : B -> Y, there exists exactly one function f : A⊕B -> Y with the property that fA = f ∘ LeftA,B and fB = f ∘ RightA,B.
To formulate this mathematically, it is quite helpful to have the information which particular Left you're working with explicit, because else the domains of the morphisms would be all unclear. In Scala this may be unnecessary because of implicit covariant conversion, but not in maths and not in Haskell.
In Haskell it isn't really an issue at all, because type inference will automatically do what's needed:
GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /tmp/haskell-stack-ghci/2a3bbd58/ghci-script
Prelude> let right2 = Right 2
Prelude> let left42 = Left 42.0
Prelude> (+) <$> right2 <*> left42
Left 42.0
Unlike, apparently, in Scala, Haskell just leaves the unspecified second argument of left42 as a type variable (unless the monomorphism restriction is enabled), so you can later use it in any context requiring some Either Double R for any type R. Of course it's possible to make that explicit too
right2 :: Either a Int
right2 = Right 2
left42 :: Either Double a
left42 = Left 42
main :: IO ()
main = print $ (+) <$> right2 <*> left42
which surely is possible in Scala just as well.
There's no meaningful drawback that I've found to your scheme. For the last eight years or so I've used my own variant of Either which is exactly as you describe under another name (Ok[+Y, +N] with Yes[+Y] and No[+N] as the alternatives). (Historical note: I started when Either was not right-biased, and wanted something that was; but then I kept using my version because it was more convenient to have only half the types.)
The only case I've ever found where it matters is when you pattern match out one branch and no longer have access to the type information of the other branch.
def foo[A, B: Typeclass](e: Either[A, B]) =
implicitly[Typeclass[B]].whatever()
// This works
myEither match {
case l: Left[L, R] => foo(l)
case r: Right[L, R] => foo(r)
}
def bar[N, Y: Typeclass](o: Ok[N, Y]) =
implicitly[Typeclass[Y]].whatever()
// This doesn't work
myOk match {
case y: Yes[Y] => bar(y) // This is fine
case n: No[N] => bar(n) // Y == Nothing!
}
However, I never do this. I could just use o to get the right type. So it doesn't matter! Everything else is easier (like pattern matching and changing one case and not the other...you don't need case Left(l) => Left(l) which rebuilds the Left for no reason except to switch the type of the uninhabited branch).
There are other cases (e.g. setting types in advance) that seem like they should be important, but in practice are almost impossible to make matter (e.g. because covariance will find the common supertype anyway, so what you set doesn't constrain anything).
So I think the decision was made before there was enough experience with the two ways to do it, and the wrong choice was made. (It's not a very wrong choice; Either is still decent.)

Efficient implementation of Catamorphisms in Scala

For a datatype representing the natural numbers:
sealed trait Nat
case object Z extends Nat
case class S(pred: Nat) extends Nat
In Scala, here is an elementary way of implementing the corresponding catamorphism:
def cata[A](z: A)(l: Nat)(f: A => A): A = l match {
case Z => z
case S(xs) => f( cata(z)(xs)(f) )
}
However, since the recursive call to cata isn't in tail position, this can easily trigger a stack overflow.
What are alternative implementation options that will avoid this? I'd rather not go down the route of F-algebras unless the interface ultimately presented by the code can look pretty much as simple as the above.
EDIT: Looks like this might be directly relevant: Is it possible to use continuations to make foldRight tail recursive?
If you were implementing a catamorphism on lists, that would be what in Haskell we call a foldr. We know that foldr does not have a tail-recursive definition, but foldl does. So if you insist on a tail-recusive program, the right thing to do is reverse the list argument (tail-recursively, in linear time), then use a foldl in place of the foldr.
Your example uses the simpler data type of naturals (and a truly "efficient" implementation would use machine integers, but we'll agree to leave that aside). What is the reverse of one of your natural numbers? Just the number itself, because we can think of it as a list with no data in each node, so we can't tell the difference when it is reversed! And what's the equivalent of the foldl? It's the program (forgive the pseudocode)
def cata(z, a, f) = {
var x = a, y = z;
while (x != Z) {
y = f(y);
x = pred(x)
}
return y
}
Or as a Scala tail-recursion,
def cata[A](z: A)(a: Nat)(f: A => A): A = a match {
case Z => z
case S(b) => cata( f(z) )(b)(f)
}
Will that do?
Yes, this is exactly the motivating example in the paper Clowns to the left of me, jokers to the right
(Dissecting Data Structures) (updated, better, but non-free version here http://dl.acm.org/citation.cfm?id=1328474).
The basic idea is that you want to turn your recursive function into a loop, so you need to figure out a data structure that keeps track of the state of the procedure, which is
What you've calculuated so far
What you have left to do.
The type of this state depends on the structure of the type you're doing the fold over, at any point in the fold you are at some node of the tree and you need to remember the tree structure of "the rest of the tree".
The paper shows how you can calculate that state type mechanically. If you do this for Lists, you get that the state you need to keep track of is
The operation run on all the previous values.
The list of elements left to process.
Which is exactly what foldl keeps track of, so it's kind of a coincidence that foldl and foldr can be given the same type.

Typeclass conversion in Haskell [duplicate]

This question already has answers here:
Haskell - Maybe Either
(4 answers)
Closed 8 years ago.
I have this assignment where I am unsure where to start. So one of the things is to do a
maybe to either conversion with this signature:
maybeEither:: Maybe a -> Either () a
and the other is of course the opposite
eitherMaybe:: Either () a -> Maybe a
so when you call one of the other they will cancel eachother out.
Now I don't really know where to begin here... Can someone help?
Extra question: How would I convert a function for example (Int->a) -> a and a -> (Int->a)
Like since in the second example you really can't give the function as a parameter to the function that converts, Im not sure how that would go.
First of all, these are not typeclasses, they're data types. If you're unfamiliar with the difference, I would recommend reading the relevant chapters in Learn You a Haskell.
To solve this particular problem, you just need to pattern match on the different constructors:
maybeEither :: Maybe a -> Either () a
maybeEither Nothing = ???
maybeEither (Just a) = ???
And
eitherMaybe :: Either () a -> Maybe a
eitherMaybe (Left x) = ???
eitherMaybe (Right y) = ???
You just need to fill in the the ???s and you're done.
For your extra question, remember that the signature a -> (Int -> a) is the same as a -> Int -> a, since -> is right associative.
Actually it's very simple, just follow the types to see what you get. The type signature of maybeEither suggests that it takes Maybe a as input.
Maybe is defined like this:
data Maybe a = Just a | Nothing
Also, from the type sigature, you can get that maybeEither gives Either () a as the output for the function.
Either type constructor is defined like this:
data Either a b = Left a | Right b
Now, replace a with () and you will get:
Either () b = Left () | Right b
Or you can replace your type variables to make it clear,
Either () a = Left () | Right a
Now, the implementation of the function is pretty straightforward.
maybeEither :: Maybe a -> Either () a
maybeEither (Just x) = ??? -- fill these
maybeEither Nothing = ???
You can follow the same approach for your other function.

Resources on managing, phasing, composing monads (in Scala or Haskell)

I am looking for resources discussing good practice for composing monads. My most pressing problem is that I'm writing a system that is making use of a series of state monads over different state types, and it seems as if the best way to handle this situation is to just create one big product type (perhaps prettied up as a record/class) encompassing all the components I'm interested in even though phase 1 is not interested in component B, and phase 2 is only interested in component A.1.
I'd appreciate pointers to nice discussions of alternatives when writing code in this sort of area. My own code-base is in Scala, but I'm happy to read discussions about the same issues in Haskell.
It's a bit challenging to use stacks of StateT because it becomes confusing as to which layer you're talking to when you write get or put. If you use an explicit stack in transformers style then you have to use a bunch of lifts and if you use the class-based method of mtl you get stuck entirely.
-- using transformers explicit stack style
type Z a = StateT Int (StateT String IO) a
go :: Z ()
go = do int <- get
str <- lift get
replicateM int (liftIO $ putStrLn str)
We might want to avoid that mess with an explicit product type of states. Since we end up with functions from our product state to each individual component it's easy to get into those individual components using gets
data ZState = ZState { int :: Int, str :: String }
type Z a = StateT ZState IO a
go :: Z ()
go = do i <- gets int
s <- gets str
replicateM i (liftIO $ putStrLn s)
But this might be considered ugly still for two reasons: (1) put and modification in general doesn't have anywhere nearly as nice a story and (2) we can't easily look at the type of a function which only impacts, say, the int state and know that it doesn't touch str. We'd much prefer to maintain that type-ensured modularity.
If you're lens-savvy there's a solution called zoom
-- the real type is MUCH more general
zoom :: Lens' mother child -> StateT child m a -> StateT mother m a
which "lifts" a stateful computation on a subpart of some larger state space up to the entire state space. Or, pragmatically, we use it like this:
data ZState = ZState { _int :: Int, _str :: String }
makeLenses ''ZState
type Z = StateT ZState IO a
inc :: MonadState Int m => m ()
inc = modify (+1)
yell :: MonadState String m => m ()
yell = modify (map toUpper)
go :: Z ()
go = do zoom int $ do inc
inc
inc
zoom str yell
i <- use int
s <- use str
replicateM i (liftIO $ putStrLn s)
And now most of the problems should have vanished—we can zoom in to isolate stateful operations which only depend upon a subset of the total state like inc and yell and determine their isolation in their type. We also can still get inner state components using use.
More than this, zoom can be used to zoom in on state buried deep inside various tranformer stacks. The fully general type works just fine in a situation like this
type Z a = EitherT String (ListT (StateT ZState IO)) a
>>> :t zoom int :: EitherT String (ListT (StateT Int IO)) a -> Z a
zoom int :: EitherT String (ListT (StateT Int IO)) a -> Z a
But while this is really nice, the fully general zoom requires some heavy trickery and you can only zoom over some transformer layers. (It's today heavily unclear to me how you add that functionality to your own layer, though presumably it's possible.)

How to get the value of a Maybe in Haskell

I'm relatively new to Haskell and began to read "Real World Haskell".
I Just stumbled over the type Maybe and have a question about how to receive the actual value from a Just 1 for example.
I have written the following code:
combine a b c = (eliminate a, eliminate b, eliminate c)
where eliminate (Just a) = a
eliminate Nothing = 0
This works fine if I use:
combine (Just 1) Nothing (Just 2)
But if I change, for example, 1 to a String it doesn't work.
I think I know why: because eliminate has to give back one type, which is, in this case, an Int. But how can I change eliminate to deal at least with Strings (or maybe with all kind of types)?
From the standard Prelude,
maybe :: b -> (a -> b) -> Maybe a -> b
maybe n _ Nothing = n
maybe _ f (Just x) = f x
Given a default value, and a function, apply the function to the value in the Maybe or return the default value.
Your eliminate could be written maybe 0 id, e.g. apply the identity function, or return 0.
From the standard Data.Maybe,
fromJust :: Maybe a -> a
fromJust Nothing = error "Maybe.fromJust: Nothing"
fromJust (Just x) = x
This is a partial function (does not return a value for every input, as opposed to a total function, which does), but extracts the value when possible.
[edit from Author, 6 years later] This is a needlessly long answer, and I'm not sure why it was accepted. Use maybe or Data.Maybe.fromMaybe as suggested in the highest upvoted answer. What follows is more of a thought experiment rather than practical advice.
So you're trying to create a function that works for a bunch of different types. This is a good time to make a class. If you've programmed in Java or C++, a class in Haskell is kind of like an interface in those languages.
class Nothingish a where
nada :: a
This class defines a value nada, which is supposed to be the class's equivalent of Nothing. Now the fun part: making instances of this class!
instance Nothingish (Maybe a) where
nada = Nothing
For a value of type Maybe a, the Nothing-like value is, well, Nothing! This will be a weird example in a minute. But before then, let's make lists an instance of this class too.
instance Nothingish [a] where
nada = []
An empty list is kind of like Nothing, right? So for a String (which is a list of Char), it will return the empty string, "".
Numbers are also an easy implementation. You've already indicated that 0 obviously represents "Nothingness" for numbers.
instance (Num a) => Nothingish a where
nada = 0
This one will actually not work unless you put a special line at the top of your file
{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}
Or when you compile it you can set the flags for these language pragmas. Don't worry about them, they're just magic that makes more stuff work.
So now you've got this class and these instances of it...now let's just re-write your function to use them!
eliminate :: (Nothingish a) => Maybe a -> a
eliminate (Just a) = a
eliminate Nothing = nada
Notice I only changed 0 to nada, and the rest is the same. Let's give it a spin!
ghci> eliminate (Just 2)
2
ghci> eliminate (Just "foo")
"foo"
ghci> eliminate (Just (Just 3))
Just 3
ghci> eliminate (Just Nothing)
Nothing
ghci> :t eliminate
eliminate :: (Nothingish t) => Maybe t -> t
ghci> eliminate Nothing
error! blah blah blah...**Ambiguous type variable**
Looks great for values and stuff. Notice the (Just Nothing) turns into Nothing, see? That was a weird example, a Maybe in a Maybe. Anyways...what about eliminate Nothing? Well, the resultant type is ambiguous. It doesn't know what we are expecting. So we have to tell it what type we want.
ghci> eliminate Nothing :: Int
0
Go ahead and try it out for other types; you'll see it gets nada for each one. So now, when you use this function with your combine function, you get this:
ghci> let combine a b c = (eliminate a, eliminate b, eliminate c)
ghci> combine (Just 2) (Just "foo") (Just (Just 3))
(2,"foo",Just 3)
ghci> combine (Just 2) Nothing (Just 4)
error! blah blah Ambiguous Type blah blah
Notice you still have to indicate what type your "Nothing" is, or indicate what return type you expect.
ghci> combine (Just 2) (Nothing :: Maybe Int) (Just 4)
(2,0,4)
ghci> combine (Just 2) Nothing (Just 4) :: (Int, Int, Int)
(2,0,4)
Or, you could restrict the types that your function allows by putting its type signature explicitly in the source. This makes sense if the logical use of the function would be that it is only used with parameters of the same type.
combine :: (Nothingish a) => Maybe a -> Maybe a -> Maybe a -> (a,a,a)
combine a b c = (eliminate a, eliminate b, eliminate c)
Now it only works if all three Maybe things are the same type. That way, it will infer that the Nothing is the same type as the others.
ghci> combine (Just 2) Nothing (Just 4)
(2,0,4)
No ambiguity, yay! But now it is an error to mix and match, like we did before.
ghci> combine (Just 2) (Just "foo") (Just (Just 3))
error! blah blah Couldn't match expected type blah blah
blah blah blah against inferred type blah blah
Well, I think that was a sufficiently long and overblown answer. Enjoy.
I'm new to Haskell too, so I don't know if this exists in the platform yet (I'm sure it does), but how about a "get or else" function to get a value if it exists, else return a default?
getOrElse::Maybe a -> a -> a
getOrElse (Just v) d = v
getOrElse Nothing d = d
This is the answer I was looking for when I came to this question:
https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Maybe.html#v:fromJust
...and similarly, for Either:
https://hackage.haskell.org/package/either-unwrap-1.1/docs/Data-Either-Unwrap.html
They provide functions I would have written myself which unwrap the value from its context.
The eliminate function's type signature is:
eliminate :: Maybe Int -> Int
That's because it returns 0 on Nothing, forcing the compiler to assume that a :: Int in your eliminate function. Hence, the compiler deduces the type signature of the combine function to be:
combine :: Maybe Int -> Maybe Int -> Maybe Int -> (Int, Int, Int)
and that's precisely why it doesn't work when you pass a String to it.
If you wrote it as:
combine a b c = (eliminate a, eliminate b, eliminate c)
where eliminate (Just a) = a
eliminate Nothing = undefined
then it would have worked with String or with any other type. The reason relies on the fact that undefined :: a, which makes eliminate polymorphic and applicable to types other than Int.
Of course, that's not the aim of your code, i.e., to make the combine function total.
Indeed, even if an application of combine to some Nothing arguments would succeed (that's because Haskell is lazy by default), as soon as you try to evaluate the results you would get a runtime error as undefined can't be evaluated to something useful (to put it in simple terms).