Haskell: safe 'show' - haskell

As part of a larger project written in Haskell, I am working on a small utility library to encapsulate common paradigms I use throughout my code. One function (or two functions, rather) that I was working on are fromLeft :: Either a b -> a and fromRight :: Either a b -> b, which are partial functions that are undefined (error to be exact) on antichiral constructors:
fromLeft :: Either a b -> a
fromLeft x = case x of
(Left x) -> x
(Right y) -> error "fromLeft: (Right _)"
fromRight :: Either a b -> b
fromRight x = case x of
(Right x) -> x
(Left y) -> error "fromRight: (Left _)"
In any case, I wanted to extend these functions if possible so that, if the y in the second pattern match for each function were of a type that were showable, it would be printed instead of "_". However, there is no obvious way to go about that without putting a constraint in the signature, which would make these functions lose their generality.
Is there any extension or module voodoo that can selectively perform typeclass functions for instances of those typeclasses and return a general result for other types? More specifically, is there any way in Haskell to write a program that simulates the invalid function
\x -> if (showable x) then show x else "_"

How about this:
fromRightWith :: (a -> String) -> Either a b -> b
fromRightWith show (Left a) = error $ "fromRight: (Left " ++ show a ++ ")"
fromRightWith _ (Right b) = b
fromRight :: Either a b -> b
fromRight = fromRightWith $ const "_"
fromRight' :: Show a => Either a b -> b
fromRight' = fromRightWith show
Then if, in your code, you know that a is an instance of Show, use fromRight'. If not, use fromRight:
instance Show MyError where
show = -- ..
trySomething :: IO (Either MyError Value)
trySomething = --- ..
main = do
value <- fromRight' <$> trySomething
-- ..

Related

Haskell IO-Monad error upon explicitly stating parameter for 'show'

Although I feel like a have a good understanding of Haskel IO and Monads, I am having a hard time understanding the following error message.
Consider the following simple function in Haskell
testf :: Show a => a -> String
testf x = show x
I tried implementing a variant that prints to the console by using an IO Monad
printtoscreen :: Show a => a -> IO()
printtoscreen x = putStrLn . show x
However, this yields the following error:
Couldn't match type ‘[Char]’ with ‘a0 -> String’
Expected type: a0 -> String
Actual type: String
The correct version should omit explicitly stating the x parameter
printtoscreen :: Show a => a -> IO()
printtoscreen = putStrLn . show
I understand why the last code snippet works, but I cannot make sense out of the error message of the second code snippet, considering that it will also return a string to putStrLn
So why should the xparameter be omitted in the IO() variant?
., the function composition operator, expects a function. show x however is not a function; it's an evaluated value (of type [Char]) by the time it's given to ..
You'd have to use the function application operator instead:
printtoscreen x = putStrLn $ show x
So why should the x parameter be omitted in the IO () variant?
This has nothing to do with IO () itself. You here use function composition. Indeed, the (.) :: (b -> c) -> (a -> b) -> a -> c function is defined as:
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g x = f (g x)
It is thus used to combine two functions f and g in a new function that first applies g to a parameter, and then f to the result of g x.
If you write:
printtoscreen x = putStrLn . show x
then the (.) function will resolve this to:
printtoscreen x = \y -> putStrLn (show x y)
or thus easier to read:
printtoscreen x y = putStrLn (show x y)
This would mean that show should have a type Show a => a -> b -> String, but it has type show :: Show a => a -> String, hence the error.

Is it possible to generate arbitrary functions in QuickCheck

I was trying to write a QuickCheck test for the identity
f $ y = f y
My initial plan was to write an arbitrary generator that returns functions & Integer, having the signature Gen (Int -> Int, Int)
and in the prop_DollerDoesNothing test that function application with / without the $ gives the same result.
This was my code:
prop_DollarDoesNothing :: Property
prop_DollarDoesNothing =
forAll arbitraryFuncInt (\(f, y) -> (f $ y) == (f y))
arbitraryFuncInt :: Gen (Int -> Int, Int)
arbitraryFuncInt = do
f <- elements [(\x -> x*2), (\x -> x+3), (\x -> x-2)]
y <- arbitrary :: Gen Int
return (f, y)
And it generated the following helpful error message:
* No instance for (Show (Int -> Int))
arising from a use of `forAll'
(maybe you haven't applied a function to enough arguments?)
* In the expression:
forAll arbitraryFuncInt (\ (f, y) -> (f $ y) == (f y))
In an equation for `prop_DollarDoesNothing':
prop_DollarDoesNothing
= forAll arbitraryFuncInt (\ (f, y) -> (f $ y) == (f y))
So, I fixed the error and got the test working by applying the arbitrary function and returning a pair of ints from arbitraryFuncInt
prop_DollarDoesNothing :: Property
prop_DollarDoesNothing =
forAll arbitraryFuncInt (\(x, y) -> x == y)
arbitraryFuncInt :: Gen (Int, Int)
arbitraryFuncInt = do
f <- elements [(\x -> x*2), (\x -> x+3), (\x -> x-2)]
y <- arbitrary :: Gen Int
return (f $ y, f y)
My questions are:
is it simply not possible to return arbitrary functions that aren't fully applied due to not having an instance for Show?
Can I write an instance for Show (Int -> Int) to make # 1 possible?
Can QuickCheck generate arbitrary functions given a type signature, for cases where I'm testing identities that are true for all functions (of a given type). Above, I specify the 3 test functions by hand, I'd like to automate that somehow, ideally something like this f <- arbitrary :: Gen (Int -> Int)
QuickCheck has support to generate, shrink and show functions, using the Fun type. CoArbitrary enables generation of functions. It is then converted to a (possibly infinite) trie-like structure, that can be inspected and shrunk to a finite value (because a test failure only depends on finitely many inputs), which can then be shown as a counterexample.
Concretely, you can write properties as function that take a Fun argument, which is a wrapper around (->) using the mechanism I described. Deconstruct it with the Fn pattern to get a function.
prop_dollarDoesNothing :: Property
prop_dollarDoesNothing = property $ \(Fn (f :: Int -> Int)) x ->
(f $ x) === f x
For more information
The QuickCheck implementation: https://hackage.haskell.org/package/QuickCheck-2.11.3/docs/Test-QuickCheck-Function.html
The paper "Shrinking and showing functions" by Koen Claessen, which appears to be paywalled, but his talk is online: https://www.youtube.com/watch?v=CH8UQJiv9Q4
Arbitrary can generate functions just fine (provided the arguments are instances of CoArbitrary), it's just the showing part that doesn't work. There's not really a good way to show a function.
This is a common problem, and therefore QuickCheck provides the Blind modifier. It basically fakes a Show instances for any type, not actually showing any information about the value. Of course this somewhat diminishes the debugging-usefulness of a failing test case, but there's not much that can done about this.

Looking for generalisation of the `if p x then x else empty` construct

I have a couple of snippets which feel like they're doing the same thing, but I'm not entirely convinced there is a generalised construct to handle them both. In one place, I have
ensure :: (String -> Bool) -> String -> String
ensure p x =
if p x then
x
else
""
This might in use look something like
ensure (/= "kim") "alex" -- returns "alex"
ensure (/= "kim") "kim" -- returns ""
in another, I have the very similar
ensure :: (a -> Bool) -> Maybe a -> Maybe a
ensure p maybeX = do
x <- maybeX
if p x then
Just x
else
Nothing
This would instead look something like
ensure even 6 -- returns Just 6
ensure even 11 -- returns Nothing
Both are checking whether a value is correct according to some predicate, and if it's not they're returning a default "empty"-looking value. There is a slight difference though – which means the second function could be rewritten as
ensure :: (Maybe a -> Bool) -> Maybe a -> Maybe a
ensure p maybeX =
if p x then
x
else
Nothing
to make them more similar, putting the responsibility of "unwrapping" the Maybe on the predicate. With this new definition, both functions would fall under
ensure :: Alternative f => (f a -> Bool) -> f a -> f a
ensure p x =
bool x empty (p x)
So, my question is,
Does this bool x empty (p x) exist in some form so I don't have to implement this function myself? The problem with inlining bool x empty (p x) is that in my case, both p and x are quite long.
Below are suggestions from the comments. One using Monoid, by 9000:
ensure :: Monoid a => (a -> Bool) -> a -> a
ensure p a = if p a then a else mempty
Another using MonadPlus, by user3237465:
ensure :: MonadPlus m => (a -> Bool) -> a -> m a
ensure p = mfilter p . return
And a variant of the second one that only requires Alternative, by Daniel Wagner:
ensure :: Alternative f => (a -> Bool) -> a -> f a
ensure p x = x <$ guard (p x)

How do I create a Show instance for b->a in Haskell?

I'm trying to construct a datatype that is essentially a binary tree whose: each node's left branch is a function that can act on the variable in each node's right branch. I'm new to Haskell, and I'm not sure I'm going about this the right way, but my current problem is that I can't figure out how to add my type to the Show typeclass. Here is my attempt:
{-# LANGUAGE ExistentialQuantification #-}
-- file: TS.hs
data TypeSentence a = forall b. Apply (TypeSentence (b->a)) (TypeSentence b)
| Expr a
instance (Show a) => (Show (TypeSentence a)) where
show (Expr x) = show x
show (Apply x y) = (show x) ++ " " ++ (show y)
instance (Show (TypeSentence b->a)) where
show (Expr x) = show "hello"
x = Expr 1
f = Expr (+1)
s = Apply f x
However, when I load this into ghci I get the following error:
TS.hs:9:24:
Could not deduce (Show (b -> a)) from the context ()
arising from a use of `show' at TS.hs:9:24-29
Possible fix:
add (Show (b -> a)) to the context of the constructor `Apply'
or add an instance declaration for (Show (b -> a))
In the first argument of `(++)', namely `(show x)'
In the expression: (show x) ++ " " ++ (show y)
In the definition of `show':
show (Apply x y) = (show x) ++ " " ++ (show y)
Failed, modules loaded: none.
Any ideas how I go about adding the Show (b->a) declaration?
Thanks.
There are a few problems with your code as written, so I'm going to go through them one by one.
You can't add a particularly informative instance for Show (a -> b). Consider how you'd have to write it:
instance Show (a -> b) where
show f = error "What goes here?"
Since f is a function, there's nothing you can do with it other than apply it to a value; and since a is a fully-polymorphic type, you can't create a value of type a to apply f to. So your only option is something like
instance Show (a -> b) where
show _ = "<function>"
As Daniel Fischer said in a comment, this is available in the Text.Show.Functions module. I wouldn't actually bother with this, though; I'd just write something like
instance Show a => Show (TypeSentence a) where
show (Apply _ x) = "Apply _ " ++ show x -- This still won't work; see below
show (Expr x) = "Expr " ++ show x
Since show can only return the one string for any function, just inline that directly.
Even then, though, you still can't write that Show instance. If you try to compile the instance above, you get the following error:
TS.hs:8:36:
Could not deduce (Show b) arising from a use of `show'
from the context (Show a)
bound by the instance declaration
at TS.hs:7:10-40
Possible fix:
add (Show b) to the context of
the data constructor `Apply'
or the instance declaration
In the second argument of `(++)', namely `show x'
In the expression: "Apply _ " ++ show x
In an equation for `show': show (Apply _ x) = "Apply _ " ++ show x
The problem is that, in your definition of TypeSentence, Apply hides a variable (bound as x in the definition of show) of TypeSentence parametrized by some arbitrary existentially-hidden type b. But there's no guarantee that b is showable, so show x won't type check, which is the error produced above: there's no instance for Show b, because b is arbitrary. So to get rid of that, the simplest approach would be
instance Show a => Show (TypeSentence a) where
show (Apply _ _) = "Apply _ _"
show (Expr x) = "Expr " ++ show x
And that's not particularly useful. So maybe there's not a good Show instance for TypeSentence. (And that's fine. Many useful types don't have Show instances.)
This one's unrelated to everything else. The instance Show (TypeSentence b -> a) declaration tries to declare an instance of Show for functions from TypeSentence b to a; if you reparenthesize that as instance Show (TypeSentence (b -> a)), you still need both the FlexibleInstances and OverlappingInstances extension to get that to compile. So that you should probably just axe.
Well, let's reason this through. Your proposed Show instance's show method will be called with some function f :: b -> a.
instance Show (b -> a) where
show f = ...
What can your show method do? Well, it must produce some String, but how will it do it?
Well, since the type of f is b -> a, the only thing you can do with f is apply it to something of type b. Yet show has no argument of type b, and your Show class doesn't have any constants of type b, so the only thing that this show method could do with f is apply it to undefined. Which may or may not produce an error, depending on whether f is strict or not—which you have no control over, and I'm sure you don't want show to error out on some arguments anyway.
But in any case, even if you did get a result from f undefined, this result it would have type a, and there really is nothing your definition can do with an a anyway, since you don't have any functions of type a -> whatever available. (And if you did have one, unless whatever was String, you'd still be in the same position.)
So there's nothing sensible you can do with f, and since you have no other arguments, this means that the only thing your method can do is return a value that doesn't depend on f or any other argument. Thus, your method's return value has to be a constant, or undefined. Since using undefined would be silly, the only sensible thing this show method can do is return a constant String:
instance Show (b -> a) where
show _ = "<function>"
As Daniel Fischer mentions in his comment to your question, this is already available in Text.Show.Functions.
But the lesson here is to take this as an example on how to reason through your question. This is one of the neat things about Haskell: you can often prove what a function can, can't or must do just by looking at the types. For example, if you have foo :: (a -> b) -> [a] -> [b], assuming foo is not silly enough doesn't use undefined gratuitously, you can infer that the bs in the [b] result are obtained by applying the a -> b type argument to elements of the [a] argument. There is no other way for foo to produce values of type b. (If you didn't guess already, the most natural function of that type is map :: (a -> b) -> [a] -> [b].)
I think the #Davorak 's comment is what you want.
https://stackoverflow.com/a/15846061/6289448
I just share it here. Pass test in ghc 8.6.5.
There is a partial solution that goes beyond just a fixed string for all functions using Data.Typeable.
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Typeable
instance (Typeable a, Typeable b) => Show (a->b) where
show _ = show $ typeOf (undefined :: a -> b)
in ghci
> let test :: Int->Int; test x = x + x
> test
Int -> Int
Unfortunately without a type signature the type will go to it default.
> let test x = x + x
> test
Integer -> Integer
This solution works on multiple function arities because a -> b -> c is the same as a -> (b -> c) which you might as well write as a -> d where d = b -> c.
> let m10 a b c d e f g h i j = a * b * c * d * e * f * g * h* i * j
> m10
Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer
-> Integer -> Integer -> Integer -> Integer
This method does not work however when it is unknown if parameters of the function have the typeable class however so while map (+1) will work map will not.
> map (+1)
[Integer] -> [Integer]
> map
<interactive>:233:1:
...
After glancing at the internals of Data.Data and an experiment or two it seems like it could be refactored to be a little more generalized cover more functions.
If you dont like implemention above, just implement it by yourself!
(Let me know If there's a better way, please!)
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE ScopedTypeVariables #-}
newtype GenType a =
GenType
{ asTypeStr :: String
}
class GenTypeArbitrary a where
gtArbitrary :: a -> GenType a
instance GenTypeArbitrary String where
gtArbitrary :: String -> GenType String
gtArbitrary _ = GenType "String123"
instance GenTypeArbitrary Bool where
gtArbitrary :: Bool -> GenType Bool
gtArbitrary _ = GenType "Bool123"
instance GenTypeArbitrary Int where
gtArbitrary :: Int -> GenType Int
gtArbitrary _ = GenType "Int123"
instance (GenTypeArbitrary a, GenTypeArbitrary b) => GenTypeArbitrary (a -> b) where
gtArbitrary :: (GenTypeArbitrary a, GenTypeArbitrary b) => (a -> b) -> GenType (a -> b)
gtArbitrary _ = GenType $ aTypeStr' ++ " --> " ++ bTypeStr
where
aTypeStr = asTypeStr (gtArbitrary (undefined :: a))
aTypeStr' =
if "-->" `isInfixOf` aTypeStr
then "(" ++ aTypeStr ++ ")"
else aTypeStr
bTypeStr = asTypeStr (gtArbitrary (undefined :: b))
instance (GenTypeArbitrary a, GenTypeArbitrary b) => Show (a -> b) where
show f = asTypeStr $ gtArbitrary f
test1 :: Int -> String
test1 x = ""
test2 :: Int -> String -> Int -> Bool -> Bool
test2 _ _ _ _ = False
test3 :: Int -> ((String -> Int) -> Bool) -> Bool
test3 _ _ = False
test4 :: Int -> (Bool -> (String -> Int)) -> Bool
test4 _ _ = False
λ > show (test4)
"Int123 --> (Bool123 --> String123 --> Int123) --> Bool123"
it :: String
...
λ > show (test3)
"Int123 --> ((String123 --> Int123) --> Bool123) --> Bool123"
it :: String
If your function's domain is a finite set then you can print the value of your function at all the points. In Haskell you can do that with the typeclasses Ix and Bounded by using a function like:
rangeF :: (Ix a, Bounded a) => [a]
rangeF = range (minBound, maxBound)

Map that associates operators with lambda functions

I have a Haskell Map, containing strings as keys and some lambda functions as items .
Eg.:
-- List of supported Operators -> mapping with functions
ops = Map.fromList [("+", \x y -> x + y),
("-", \x y -> y - x),
("*", \x y -> x * y),
("/", \x y -> y / x)]
I want to write a function that takes as input:
A string representing an operator ["+", "-", "*", "/"]
Two numbers
Based on the operator and the ops map, the function will evaluate the sum/subtraction/etc. of the two numbers .
I've tried something like:
(Map.lookup "+" a) 1 2
But it's not working .
The error is:
Top level:
No instance for (Show (Integer -> Integer))
arising from use of `print' at Top level
Probable fix: add an instance declaration for (Show (Integer
In a 'do' expression: print it
<interactive>:1:1:
No instance for (Monad ((->) t))
arising from use of `Data.Map.lookup' at <interactive>:1:1-
Probable fix: add an instance declaration for (Monad ((->) t)
In the definition of `it': it = (Data.Map.lookup "+" a) 1 2
... not very helpful for me.
Any suggestions ? Thank you !
lookup is of type lookup :: Ord k => k -> Map k a -> Maybe a. The result is wrapped in a Maybe to indicate that the key may not be present in the map.
Here's a way to do it that will work:
runOp :: String -> a -> a -> b
runOp key x y = case lookup key ops of
Just op -> op x y
Nothing -> error ("Couldn't find operator: " ++ key)
This will bottom out if the key is not present. You could also return an Either or Maybe result from runOp to accommodate the possibility that the key isn't present, but that's up to you.
Maybe is defined as follows:
data Maybe a = Just a | Nothing
that is, it either holds a result value or an empty value. Like an existential philosopher, Haskell forces you to acknowledge the possibility of Nothing.
First of all the error you showed is not caused by the code you showed. Your code causes the following error (in ghc):
Couldn't match expected type `t1 -> t2 -> t'
against inferred type `Data.Maybe.Maybe
That error is caused by the fact that lookup returns a Maybe. So you need to unwrap the Maybe first.
import Control.Applicative
ops :: (Fractional a) => Map.Map String (a -> a -> a)
ops = Map.fromList [("+", (+)),
("-", flip (-)),
("*", (*)),
("/", flip (/))]
apply :: (Fractional a) => String -> a -> a -> Maybe a
apply op x y = Map.lookup op ops <*> y <*> x
Because lookup returns a Maybe a (well, Maybe (a -> a -> a) in this case), there is no way to directly apply it to an a. We can use <*> to pull the LHS out of the mote, apply it to the RHS, and inject it back into the monad. (Or do it manually like Bill.)

Categories

Resources