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

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.

Related

Can a type correct function be inapplicable? (Haskell)

I have a function foo = \f x -> let c = \y -> x in f c which I have type inferenced to find :
\forall a,b,r. ((b -> a) -> r) -> a -> r.
GHCI confirms this type: foo :: ((p1 -> p2) -> t) -> p2 -> t
However, I am unable to find an applicable function that meets these parameters such that foo evaluates.
I have tried the following functions with no success:
bu :: Num a => ([Char] -> a) -> a
bu x = (x "hello") * 2
ba :: (Fractional a1, Foldable t) => t a2 -> a1
ba x = (fromIntegral (length x) ) / 2
Another attempt was choosing the following functions:
bu :: Num a => ([Char] -> a) -> a -> a
bu x = (+ ((x "hello") * 2))
ba :: (Fractional a1, Foldable t) => t a2 -> a1
ba x = (fromIntegral (length x) ) / 2
Now I can call (bu ba) 4and get a correct result.
I understand why those don't work.
The issue seems to be that in the first arguement (p1 -> p2) -> t), t would need to be a function that takes the argument p2. However, as soon as we do that the type of that function changes to something like (a -> a) and can no longer be correctly consumed by foo.
This exercise has lead me to the question; can a function with a correct type be inapplicable?
My intuition leads me to believe that this is false and that an applicable input exists for any function with a valid type. Is there a proof for this?
Here is a simple proof that a function can be inapplicable (disregarding bottoms)
data Never = Never Never
justTryIt :: Never -> ()
justTryIt _ = ()
However your function IS applicable
main = print $ foo (\c -> c ()) 3
So what is the type of that lambda?
g :: (() -> a) -> a
g = \c -> c ()
Point is you don't need a function of
g :: (a -> b) -> c
Which is uninhabited (iGnOrInG bOtToMs). The type signature is just saying you can take a function where all 3 of those type (forall a b c.) can vary. IE this works equally as well
g :: (Int -> String) -> Bool
g f = null $ f 3
main = print $ foo g "so concrete"
A function of type p1 -> p2 is impossible to write; that basically says "given any possible type, I can give you any other possible type". Good luck with that!
The type (p1 -> p2) -> t is impossible for a similar reason. However, (p1 -> p2) -> Bool is quite possible:
f :: (p1 -> p2) -> Bool
f x = True
You can write similar functions for various choices of type t. (What you can't do is write a function that can somehow return any possible t out of nothing.)
More generally, can every implementable function be successfully called? That's an interesting question. I'm not sure what the answer is. I'd love to know!
EDIT: Thinking about it... the type signature of every implementable function can be interpreted as a theorum (and the implementation of the function is in some sense a "proof" of that theorum). A function that takes another function as input is like "this theorum is true if this other theorum is true". So if you can come up with a proof that "X is true if Y is true", where Y is definitely false... then you have your implementable function that can never be called.
All of this cheerfully ignores that real Haskell has several ways to break the type system and get around these nice results. For example, the function error "banana" has type a (i.e., any possible type). So in this "cheating" sense, all Haskell functions are callable.

How does `return` statement have different type than that of a function's definition?

Within a loop, integers are collected inside a list, and a tuple of these integers is returned. How does this change to a list of tuples?
input :: IO [(Int,Int)]
input = do
n <- readLn :: IO Int
forM [1..n] $ \_ -> do
[x,y] <- map read . words <$> getLine
return (x,y)
I expected type of value to be (Int,Int) but it is [(Int,Int)]. Why?
Let's re-write your code with explicit separators making the code structure more self-apparent:
input :: IO [(Int,Int)]
input = do {
n <- readLn ;
forM [1..n] (\ _ -> do {
[x,y] <- fmap (map read . words) getLine ;
return (x,y) })
}
so return (x,y) belongs to the internal do.
Since there's a getLine :: IO String there, the internal do's type is IO (t1,t2) where x :: t1, y :: t2. So this is also the return type of that lambda function participating in that forM call.
Since forM :: Monad m => [a] -> (a -> m b) -> m [b], and we know m ~ IO here, we get the type of the overall do's last expression as
forM :: [a] -> (a -> IO b) -> IO [b]
and thus the overall type is IO [b] ~ IO [(t1,t2)] since b ~ (t1,t2) as per that return expression.
The lambda function returns IO b so forM returns IO [b] as per its type above. And the type of do block is the same as the type of its last expression.
The function's signature says it's IO [(Int,Int)], so finally t1 ~ Int and t2 ~ Int and everything fits.

How does `<$` function work in the Functor class?

In the Functor class definition we have the <$ function defined as:
class Functor f where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
(<$) = fmap . const
The const function has the definition:
const :: a -> b -> a
const x _ = x
I know that the <$ function is equivalent to:
\x -> fmap (const x)
How does fmap . const equate to the lambda expression above? My understanding of function composition is that output type of const should match the input type of fmap, but the input type of fmap is the function (a -> b) not a which is what the const function outputs.
Note that:
(f . g) x = f (g x)
(see the definition of (.)) so,
(fmap . const) x = fmap (const x)
Original Answer
For concreteness, let's use the IO functor.
fmap f work on an IO-computation by applying f to the result of the computation.
E.g. - getContents is an IO String, and length is a function on Strings, so we can fmap length on getContents:
getContents :: IO String
length :: String -> Int
fmap length getContents :: IO Int
When run this would read all of standard input, take the length of the input, and return it (as an IO-action).
Now, const z is a function which ignores its argument and always returns z. So if I were to fmap (const 'w') on getContents I would have:
getContents :: IO String
const 'w' :: String -> Char
fmap (const 'w') getContents :: IO Char
When executed, this would first read in all of standard input, then discard that input and return the character 'w'.
The other answer does a good job of addressing the question, "How does fmap . const equate to the lambda expression above?", so I want to address a different part:
My understanding of function composition is that output type of const should match the input type of fmap, but the input type of fmap is the function (a -> b) not a which is what the const function outputs.
In this answer, I will argue that the output type of const is indeed a function as needed by fmap.
Let's rewrite the types of fmap and const, using separate type variables in each to avoid confusion:
fmap :: Functor f => (a -> b) -> (f a -> f b)
const :: c -> (d -> c)
Now, one must ask: what is the output type of const? In your question, you posit that the output type is c (after correcting for type variable renaming as above). But in fact this is a slight misunderstanding; the true output type is d -> c!
The output of const is actually a function. Now, as you say, its output must match the input of fmap. With our naming above, this means we must choose to satisfy the equation d ~ a (read: type d and type a are the same type) and satisfy c ~ b. Then we will have:
const :: b -> (a -> b)
fmap :: (a -> b) -> (f a -> f b)
fmap . const :: b -> (f a -> f b)

Haskell: safe 'show'

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
-- ..

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.)

Resources