Composing two error-raising functions in Haskell - function

The problem I have been given says this:
In a similar way to mapMaybe, define
the function:
composeMaybe :: (a->Maybe b) -> (b -> Maybe c) -> (a-> Maybe c)
which composes two error-raising functions.
The type Maybe a and the function mapMaybe are coded like this:
data Maybe a = Nothing | Just a
mapMaybe g Nothing = Nothing
mapMaybe g (Just x) = Just (g x)
I tried using composition like this:
composeMaybe f g = f.g
But it does not compile.
Could anyone point me in the right direction?

The tool you are looking for already exists. There are two Kleisli composition operators in Control.Monad.
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
When m = Maybe, the implementation of composeMaybe becomes apparent:
composeMaybe = (>=>)
Looking at the definition of (>=>),
f >=> g = \x -> f x >>= g
which you can inline if you want to think about it in your own terms as
composeMaybe f g x = f x >>= g
or which could be written in do-sugar as:
composeMaybe f g x = do
y <- f x
g y
In general, I'd just stick to using (>=>), which has nice theoretical reasons for existing, because it provides the cleanest way to state the monad laws.

First of all: if anything it should be g.f, not f.g because you want a function which takes the same argument as f and gives the same return value as g. However that doesn't work because the return type of f does not equal the argument type of g (the return type of f has a Maybe in it and the argument type of g does not).
So what you need to do is: Define a function which takes a Maybe b as an argument. If that argument is Nothing, it should return Nothing. If the argument is Just b, it should return g b. composeMaybe should return the composition of the function with f.

Here is an excellent tutorial about Haskell monads (and especially the Maybe monad, which is used in the first examples).

composeMaybe :: (a -> Maybe b)
-> (b -> Maybe c)
-> (a -> Maybe c)
composeMaybe f g = \x ->
Since g takes an argument of type b, but f produces a value of type Maybe b, you have to pattern match on the result of f x if you want to pass that result to g.
case f x of
Nothing -> ...
Just y -> ...

A very similar function already exists — the monadic bind operator, >>=. Its type (for the Maybe monad) is Maybe a -> (a -> Maybe b) -> Maybe b, and it's used like this:
Just 100 >>= \n -> Just (show n) -- gives Just "100"
It's not exactly the same as your composeMaybe function, which takes a function returning a Maybe instead of a direct Maybe value for its first argument. But you can write your composeMaybe function very simply with this operator — it's almost as simple as the definition of the normal compose function, (.) f g x = f (g x).

Notice how close the types of composeMaybe's arguments are to what the monadic bind operator wants for its latter argument:
ghci> :t (>>=)
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b
The order of f and g is backward for composition, so how about a better name?
thenMaybe :: (a -> Maybe b) -> (b -> Maybe c) -> (a -> Maybe c)
thenMaybe f g = (>>= g) . (>>= f) . return
Given the following definitions
times3 x = Just $ x * 3
saferecip x
| x == 0 = Nothing
| otherwise = Just $ 1 / x
one can, for example,
ghci> saferecip `thenMaybe` times3 $ 4
Just 0.75
ghci> saferecip `thenMaybe` times3 $ 8
Just 0.375
ghci> saferecip `thenMaybe` times3 $ 0
Nothing
ghci> times3 `thenMaybe` saferecip $ 0
Nothing
ghci> times3 `thenMaybe` saferecip $ 1
Just 0.3333333333333333

Related

currying in haskell when the uncurried form is known

I've been learning currying in Haskell and now trying to write the Haskell type signature of a function in curried form, whose uncurried form has an argument pair of type (x, y) and a value of type x as its result. I think the correct approach would be f :: (y,x) -> x, but I'm not sure. Is it correct, and if not, why?
You can let ghci do this for you.
> f = undefined :: (a, b) -> c
> :t curry f
curry f :: a -> b -> c
You can uncurry the result to get back the original type.
> :t uncurry (curry f)
uncurry (curry f) :: (a, b) -> c
The actual implementation of curry is, perhaps, more enlightening.
curry :: ((a, b) -> c) -> a -> b -> c
curry f = \x -> \y -> f (x, y)
If f expects a tuple, then curry f simply packages its two arguments into a tuple to pass to f.
Examples are hard to come by, as functions in Haskell are usually fully curried already. But we can explicitly uncurry a binary operator to construct an example.
> (+) 3 5
8
> f = uncurry (+)
> f (3, 5)
8
> (curry f) 3 5
8
As an aside, the type you suggested is what you would get by inserting a call to flip between currying and uncurrying a function:
> :t uncurry . flip . curry
uncurry . flip . curry :: ((b, a) -> c) -> (a, b) -> c
To see this in action, you'd have to pick a non-commutative operator, like (++).
> strconcat = uncurry (++)
> strconcat ("foo", "bar")
"foobar"
> (uncurry . flip . curry) strconcat ("foo", "bar")
"barfoo"
Just swapping the elements of the tuple is not currying. You have to get rid of the tuple altogether. You can do that by taking the first element of the tuple as argument and returning a function which takes the second element of the tuple and finally returns the result type. In your case the type would be f :: x -> (y -> x), these parenthesis are redundant, it is the same as f :: x -> y -> x. This is the curried form.

How to Implement functions from type signatures?

I have the following two type signatures in Haskell:
foo :: (a -> (a,b)) -> a -> [b]
bar :: (a -> b) -> (a -> b -> c) -> a -> c
I want to write a concrete implementation of these two functions but I'm really struggling to understand where to start.
I understand that foo takes a function (a -> (a,b)) and returns a and a list containing b.
And bar takes a function (b -> c) which returns a function (a -> b -> c) which finally returns a and c.
Can anyone show me an example of a concrete implementation?
How do I know where to start with something like this and what goes on the left side of the definition?
You have some misunderstandings there:
I understand that foo takes a function (a -> (a,b)) and returns a and a list containing b.
No, it doesn't return a. It expects it as another argument, in addition to that function.
And bar takes a function (b -> c) which returns a function (a -> b -> c) which finally returns a and c.
Same here. Given g :: a -> b, bar returns a function bar g :: (a -> b -> c) -> a -> c. This function, in turn, given a function h :: (a -> b -> c), returns a function of type a -> c. And so it goes.
It's just like playing with pieces of a puzzle:
foo :: (a -> (a,b)) -> a -> [b]
-- g :: a -> (a,b)
-- x :: a
-- g x :: (a,b)
foo g x = [b] where
(a,b) = g x
bar :: (a -> b) -> (a -> b -> c) -> a -> c
-- g :: a -> b
-- x :: a
-- g x :: b
-- h :: a -> b -> c
-- h x :: b -> c
-- h x (g x) :: c
bar g h x = c where
c = ....
There's not much free choice for us here. Although, there are more ways to get more values of type b, for foo. Instead of ignoring that a in (a,b) = g x, we can use it in more applications of g, so there actually are many more possibilities there, like
foo2 :: (a -> (a,b)) -> a -> [b]
foo2 g x = [b1,b2] where
(a1,b1) = g x
(a2,b2) = g a1
and many more. Still, the types guide the possible implementations. foo can even make use of foo in its implementation, according to the types:
foo3 :: (a -> (a,b)) -> a -> [b]
foo3 g x = b : bs where
(a,b) = g x
bs = ...
So now, with this implementation, the previous two become its special cases: foo g x === take 1 (foo3 g x) and foo2 g x === take 2 (foo3 g x). Having the most general definition is probably best.
In addition to #will-nes's answer, it will be useful to treat (->) as a right-associative infix operator. So something like f: a -> b -> c is the same as f: a -> (b -> c). So this is saying f is a function that takes a value of type a and returns you a value of type b -> c, which is, another function, one that takes a value of type b and returns you a value of type c.
So the types in your example can be re-written as follows
foo :: (a -> (a,b)) -> (a -> [b])
bar :: (a -> b) -> ((a -> (b -> c)) -> (a -> c))
Similarly, you can think of arguments to a function in pieces as well, as being left-associative (like + and -), though there's no explicit operator in this case. foo a b c d e is the same as ((((foo a) b) c) d) e. For example, let's say we have a function f: Int -> Int -> Int (which is the same as f: Int -> (Int -> Int)). You don't have to provide both arguments at once. So you can write g = f 1, which has the type (Int -> Int). And then you can provide an argument to g, like g 2, which has the type Int. f 1 2 and let g = f 1 in g 2 are more or less the same. Here's a more concrete example of how this works:
Prelude> f = (+)
Prelude> g = f 1
Prelude> g 2
3
Prelude> :t f
f :: Num a => a -> a -> a
Prelude> :t g
g :: Num a => a -> a
Prelude> :t g 2
g 2 :: Num a => a
In #will-nes's sample implementation examples, he defines the functions with all of the arguments up front, but you don't have to think of them that way. Just think of f: a -> b -> c as taking a value of type a and returning another function. While most of the methods you encounter will use all of their arguments up-front, there might be cases in which you don't want to do that. Here's an example:
veryExpensive :: A -> B
unstagedFun :: A -> (B -> C) -> C
unstagedFun a f = f (veryExpensive a)
stagedFun :: A -> (B -> C) -> C
stagedFun a = let b = veryExpensive a in \f -> f b
(You can also rewrite the latter as let b = veryExpensive a in ($ b))
Of course, with compiler optimizations, I wouldn't be surprised if the unstaged version staged automatically, but hopefully this offers some motivation for thinking of functions as not having multiple arguments, but rather, as a single argument, but they may return other functions that may themselves return functions (but also only take a single argument).

Finding inverse functions [duplicate]

In pure functional languages like Haskell, is there an algorithm to get the inverse of a function, (edit) when it is bijective? And is there a specific way to program your function so it is?
In some cases, yes! There's a beautiful paper called Bidirectionalization for Free! which discusses a few cases -- when your function is sufficiently polymorphic -- where it is possible, completely automatically to derive an inverse function. (It also discusses what makes the problem hard when the functions are not polymorphic.)
What you get out in the case your function is invertible is the inverse (with a spurious input); in other cases, you get a function which tries to "merge" an old input value and a new output value.
No, it's not possible in general.
Proof: consider bijective functions of type
type F = [Bit] -> [Bit]
with
data Bit = B0 | B1
Assume we have an inverter inv :: F -> F such that inv f . f ≡ id. Say we have tested it for the function f = id, by confirming that
inv f (repeat B0) -> (B0 : ls)
Since this first B0 in the output must have come after some finite time, we have an upper bound n on both the depth to which inv had actually evaluated our test input to obtain this result, as well as the number of times it can have called f. Define now a family of functions
g j (B1 : B0 : ... (n+j times) ... B0 : ls)
= B0 : ... (n+j times) ... B0 : B1 : ls
g j (B0 : ... (n+j times) ... B0 : B1 : ls)
= B1 : B0 : ... (n+j times) ... B0 : ls
g j l = l
Clearly, for all 0<j≤n, g j is a bijection, in fact self-inverse. So we should be able to confirm
inv (g j) (replicate (n+j) B0 ++ B1 : repeat B0) -> (B1 : ls)
but to fulfill this, inv (g j) would have needed to either
evaluate g j (B1 : repeat B0) to a depth of n+j > n
evaluate head $ g j l for at least n different lists matching replicate (n+j) B0 ++ B1 : ls
Up to that point, at least one of the g j is indistinguishable from f, and since inv f hadn't done either of these evaluations, inv could not possibly have told it apart – short of doing some runtime-measurements on its own, which is only possible in the IO Monad.
                                                                                                                                   ⬜
You can look it up on wikipedia, it's called Reversible Computing.
In general you can't do it though and none of the functional languages have that option. For example:
f :: a -> Int
f _ = 1
This function does not have an inverse.
Not in most functional languages, but in logic programming or relational programming, most functions you define are in fact not functions but "relations", and these can be used in both directions. See for example prolog or kanren.
Tasks like this are almost always undecidable. You can have a solution for some specific functions, but not in general.
Here, you cannot even recognize which functions have an inverse. Quoting Barendregt, H. P. The Lambda Calculus: Its Syntax and Semantics. North Holland, Amsterdam (1984):
A set of lambda-terms is nontrivial if it is neither the empty nor the full set. If A and B are two nontrivial, disjoint sets of lambda-terms closed under (beta) equality, then A and B are recursively inseparable.
Let's take A to be the set of lambda terms that represent invertible functions and B the rest. Both are non-empty and closed under beta equality. So it's not possible to decide whether a function is invertible or not.
(This applies to the untyped lambda calculus. TBH I don't know if the argument can be directly adapted to a typed lambda calculus when we know the type of a function that we want to invert. But I'm pretty sure it will be similar.)
If you can enumerate the domain of the function and can compare elements of the range for equality, you can - in a rather straightforward way. By enumerate I mean having a list of all the elements available. I'll stick to Haskell, since I don't know Ocaml (or even how to capitalise it properly ;-)
What you want to do is run through the elements of the domain and see if they're equal to the element of the range you're trying to invert, and take the first one that works:
inv :: Eq b => [a] -> (a -> b) -> (b -> a)
inv domain f b = head [ a | a <- domain, f a == b ]
Since you've stated that f is a bijection, there's bound to be one and only one such element. The trick, of course, is to ensure that your enumeration of the domain actually reaches all the elements in a finite time. If you're trying to invert a bijection from Integer to Integer, using [0,1 ..] ++ [-1,-2 ..] won't work as you'll never get to the negative numbers. Concretely, inv ([0,1 ..] ++ [-1,-2 ..]) (+1) (-3) will never yield a value.
However, 0 : concatMap (\x -> [x,-x]) [1..] will work, as this runs through the integers in the following order [0,1,-1,2,-2,3,-3, and so on]. Indeed inv (0 : concatMap (\x -> [x,-x]) [1..]) (+1) (-3) promptly returns -4!
The Control.Monad.Omega package can help you run through lists of tuples etcetera in a good way; I'm sure there's more packages like that - but I don't know them.
Of course, this approach is rather low-brow and brute-force, not to mention ugly and inefficient! So I'll end with a few remarks on the last part of your question, on how to 'write' bijections. The type system of Haskell isn't up to proving that a function is a bijection - you really want something like Agda for that - but it is willing to trust you.
(Warning: untested code follows)
So can you define a datatype of Bijection s between types a and b:
data Bi a b = Bi {
apply :: a -> b,
invert :: b -> a
}
along with as many constants (where you can say 'I know they're bijections!') as you like, such as:
notBi :: Bi Bool Bool
notBi = Bi not not
add1Bi :: Bi Integer Integer
add1Bi = Bi (+1) (subtract 1)
and a couple of smart combinators, such as:
idBi :: Bi a a
idBi = Bi id id
invertBi :: Bi a b -> Bi b a
invertBi (Bi a i) = (Bi i a)
composeBi :: Bi a b -> Bi b c -> Bi a c
composeBi (Bi a1 i1) (Bi a2 i2) = Bi (a2 . a1) (i1 . i2)
mapBi :: Bi a b -> Bi [a] [b]
mapBi (Bi a i) = Bi (map a) (map i)
bruteForceBi :: Eq b => [a] -> (a -> b) -> Bi a b
bruteForceBi domain f = Bi f (inv domain f)
I think you could then do invert (mapBi add1Bi) [1,5,6] and get [0,4,5]. If you pick your combinators in a smart way, I think the number of times you'll have to write a Bi constant by hand could be quite limited.
After all, if you know a function is a bijection, you'll hopefully have a proof-sketch of that fact in your head, which the Curry-Howard isomorphism should be able to turn into a program :-)
I've recently been dealing with issues like this, and no, I'd say that (a) it's not difficult in many case, but (b) it's not efficient at all.
Basically, suppose you have f :: a -> b, and that f is indeed a bjiection. You can compute the inverse f' :: b -> a in a really dumb way:
import Data.List
-- | Class for types whose values are recursively enumerable.
class Enumerable a where
-- | Produce the list of all values of type #a#.
enumerate :: [a]
-- | Note, this is only guaranteed to terminate if #f# is a bijection!
invert :: (Enumerable a, Eq b) => (a -> b) -> b -> Maybe a
invert f b = find (\a -> f a == b) enumerate
If f is a bijection and enumerate truly produces all values of a, then you will eventually hit an a such that f a == b.
Types that have a Bounded and an Enum instance can be trivially made RecursivelyEnumerable. Pairs of Enumerable types can also be made Enumerable:
instance (Enumerable a, Enumerable b) => Enumerable (a, b) where
enumerate = crossWith (,) enumerate enumerate
crossWith :: (a -> b -> c) -> [a] -> [b] -> [c]
crossWith f _ [] = []
crossWith f [] _ = []
crossWith f (x0:xs) (y0:ys) =
f x0 y0 : interleave (map (f x0) ys)
(interleave (map (flip f y0) xs)
(crossWith f xs ys))
interleave :: [a] -> [a] -> [a]
interleave xs [] = xs
interleave [] ys = []
interleave (x:xs) ys = x : interleave ys xs
Same goes for disjunctions of Enumerable types:
instance (Enumerable a, Enumerable b) => Enumerable (Either a b) where
enumerate = enumerateEither enumerate enumerate
enumerateEither :: [a] -> [b] -> [Either a b]
enumerateEither [] ys = map Right ys
enumerateEither xs [] = map Left xs
enumerateEither (x:xs) (y:ys) = Left x : Right y : enumerateEither xs ys
The fact that we can do this both for (,) and Either probably means that we can do it for any algebraic data type.
Not every function has an inverse. If you limit the discussion to one-to-one functions, the ability to invert an arbitrary function grants the ability to crack any cryptosystem. We kind of have to hope this isn't feasible, even in theory!
In some cases, it is possible to find the inverse of a bijective function by converting it into a symbolic representation. Based on this example, I wrote this Haskell program to find inverses of some simple polynomial functions:
bijective_function x = x*2+1
main = do
print $ bijective_function 3
print $ inverse_function bijective_function (bijective_function 3)
data Expr = X | Const Double |
Plus Expr Expr | Subtract Expr Expr | Mult Expr Expr | Div Expr Expr |
Negate Expr | Inverse Expr |
Exp Expr | Log Expr | Sin Expr | Atanh Expr | Sinh Expr | Acosh Expr | Cosh Expr | Tan Expr | Cos Expr |Asinh Expr|Atan Expr|Acos Expr|Asin Expr|Abs Expr|Signum Expr|Integer
deriving (Show, Eq)
instance Num Expr where
(+) = Plus
(-) = Subtract
(*) = Mult
abs = Abs
signum = Signum
negate = Negate
fromInteger a = Const $ fromIntegral a
instance Fractional Expr where
recip = Inverse
fromRational a = Const $ realToFrac a
(/) = Div
instance Floating Expr where
pi = Const pi
exp = Exp
log = Log
sin = Sin
atanh = Atanh
sinh = Sinh
cosh = Cosh
acosh = Acosh
cos = Cos
tan = Tan
asin = Asin
acos = Acos
atan = Atan
asinh = Asinh
fromFunction f = f X
toFunction :: Expr -> (Double -> Double)
toFunction X = \x -> x
toFunction (Negate a) = \a -> (negate a)
toFunction (Const a) = const a
toFunction (Plus a b) = \x -> (toFunction a x) + (toFunction b x)
toFunction (Subtract a b) = \x -> (toFunction a x) - (toFunction b x)
toFunction (Mult a b) = \x -> (toFunction a x) * (toFunction b x)
toFunction (Div a b) = \x -> (toFunction a x) / (toFunction b x)
with_function func x = toFunction $ func $ fromFunction x
simplify X = X
simplify (Div (Const a) (Const b)) = Const (a/b)
simplify (Mult (Const a) (Const b)) | a == 0 || b == 0 = 0 | otherwise = Const (a*b)
simplify (Negate (Negate a)) = simplify a
simplify (Subtract a b) = simplify ( Plus (simplify a) (Negate (simplify b)) )
simplify (Div a b) | a == b = Const 1.0 | otherwise = simplify (Div (simplify a) (simplify b))
simplify (Mult a b) = simplify (Mult (simplify a) (simplify b))
simplify (Const a) = Const a
simplify (Plus (Const a) (Const b)) = Const (a+b)
simplify (Plus a (Const b)) = simplify (Plus (Const b) (simplify a))
simplify (Plus (Mult (Const a) X) (Mult (Const b) X)) = (simplify (Mult (Const (a+b)) X))
simplify (Plus (Const a) b) = simplify (Plus (simplify b) (Const a))
simplify (Plus X a) = simplify (Plus (Mult 1 X) (simplify a))
simplify (Plus a X) = simplify (Plus (Mult 1 X) (simplify a))
simplify (Plus a b) = (simplify (Plus (simplify a) (simplify b)))
simplify a = a
inverse X = X
inverse (Const a) = simplify (Const a)
inverse (Mult (Const a) (Const b)) = Const (a * b)
inverse (Mult (Const a) X) = (Div X (Const a))
inverse (Plus X (Const a)) = (Subtract X (Const a))
inverse (Negate x) = Negate (inverse x)
inverse a = inverse (simplify a)
inverse_function x = with_function inverse x
This example only works with arithmetic expressions, but it could probably be generalized to work with lists as well. There are also several implementations of computer algebra systems in Haskell that may be used to find the inverse of a bijective function.
No, not all functions even have inverses. For instance, what would the inverse of this function be?
f x = 1

How does fmap fmap apply to functions (as arguments)?

I am trying to understand how fmap fmap applies to a function like say (*3).
The type of fmap fmap:
(fmap fmap):: (Functor f1, Functor f) => f (a -> b) -> f (f1 a -> f1 b)
Type of (*3):
(*3) :: Num a => a -> a
Which means that the signature a -> a corresponds to f (a -> b), right?
Prelude> :t (fmap fmap (*3))
(fmap fmap (*3)):: (Num (a -> b), Functor f) => (a -> b) -> f a -> f b
I have tried creating a simple test:
test :: (Functor f) => f (a -> b) -> Bool
test f = True
And feeding (*3) into it, but I get:
*Main> :t (test (*3))
<interactive>:1:8:
No instance for (Num (a0 -> b0)) arising from a use of ‘*’
In the first argument of ‘test’, namely ‘(* 3)’
In the expression: (test (* 3))
Why is that happening?
Polymorphism is dangerous when you do not know what you are doing. Both fmap and (*) are polymorphic functions and using them blindly can lead to very confusing (and possibly incorrect) code. I have answered a similar question before:
What is happening when I compose * with + in Haskell?
In such cases, I believe that looking at the types of values can help you figure out where you are going wrong and how to rectify the problem. Let's start with the type signature of fmap:
fmap :: Functor f => (a -> b) -> f a -> f b
|______| |________|
| |
domain codomain
The type signature of fmap is easy to understand. It lifts a function from a to b into the context of a functor, whatever that functor may be (e.g. list, maybe, either, etc.).
The words "domain" and "codomain" just mean "input" and "output" respectively. Anyway, let's see what happens when we apply fmap to fmap:
fmap :: Functor f => (a -> b) -> f a -> f b
|______|
|
fmap :: Functor g => (x -> y) -> g x -> g y
|______| |________|
| |
a -> b
As you can see, a := x -> y and b := g x -> g y. In addition, the Functor g constraint is added. This gives us the type signature of fmap fmap:
fmap fmap :: (Functor f, Functor g) => f (x -> y) -> f (g x -> g y)
So, what does fmap fmap do? The first fmap has lifted the second fmap into the context of a functor f. Let's say that f is Maybe. Hence, on specializing:
fmap fmap :: Functor g => Maybe (x -> y) -> Maybe (g x -> g y)
Hence fmap fmap must be applied to a Maybe value with a function inside it. What fmap fmap does is that it lifts the function inside the Maybe value into the context of another functor g. Let's say that g is []. Hence, on specializing:
fmap fmap :: Maybe (x -> y) -> Maybe ([x] -> [y])
If we apply fmap fmap to Nothing then we get Nothing. However, if we apply it to Just (+1) then we get a function that increments every number of a list, wrapped in a Just constructor (i.e. we get Just (fmap (+1))).
However, fmap fmap is more general. What it actually does it that it looks inside a functor f (whatever f may be) and lifts the function(s) inside f into the context of another functor g.
So far so good. So what's the problem? The problem is when you apply fmap fmap to (*3). This is stupid and dangerous, like drinking and driving. Let me tell you why it's stupid and dangerous. Take a look at the type signature of (*3):
(*3) :: Num a => a -> a
When you apply fmap fmap to (*3) then the functor f is specialized to (->) r (i.e. a function). A function is a valid functor. The fmap function for (->) r is simply function composition. Hence, the type of fmap fmap on specializing is:
fmap fmap :: Functor g => (r -> x -> y) -> r -> g x -> g y
-- or
(.) fmap :: Functor g => (r -> x -> y) -> r -> g x -> g y
|___________|
|
(*3) :: Num a => a -> a
| |
| ------
| | |
r -> x -> y
Do you see why it's stupid and dangerous?
It's stupid because you are applying a function which expects an input function with two arguments (r -> x -> y) to a function with only one argument, (*3) :: Num a => a -> a.
It's dangerous because the output of (*3) is polymorphic. Hence, the compiler doesn't tell you that you are doing something stupid. Luckily, because the output is bounded you get a type constraint Num (x -> y) which should indicate that you have gone wrong somewhere.
Working out the types, r := a := x -> y. Hence, we get the following type signature:
fmap . (*3) :: (Num (x -> y), Functor g) => (x -> y) -> g x -> g y
Let me show you why it's wrong using values:
fmap . (*3)
= \x -> fmap (x * 3)
|_____|
|
+--> You are trying to lift a number into the context of a functor!
What you really want to do is apply fmap fmap to (*), which is a binary function:
(.) fmap :: Functor g => (r -> x -> y) -> r -> g x -> g y
|___________|
|
(*) :: Num a => a -> a -> a
| | |
r -> x -> y
Hence, r := x := y := a. This gives you the type signature:
fmap . (*) :: (Num a, Functor g) => a -> g a -> g a
This makes even more sense when you see the values:
fmap . (*)
= \x -> fmap (x *)
Hence, fmap fmap (*) 3 is simply fmap (3*).
Finally, you have the same problem with your test function:
test :: Functor f => f (a -> b) -> Bool
On specializing functor f to (->) r we get:
test :: (r -> a -> b) -> Bool
|___________|
|
(*3) :: Num x => x -> x
| |
| ------
| | |
r -> a -> b
Hence, r := x := a -> b. Thus we get type signature:
test (*3) :: Num (a -> b) => Bool
Since neither a nor b appear in the output type, the constraint Num (a -> b) must be resolved immediately. If a or b appeared in the output type then they could be specialized and a different instance of Num (a -> b) could be chosen. However, because they don't appear in the output type the compiler has to decide which instance of Num (a -> b) to choose immediately; and because Num (a -> b) is a stupid constraint which doesn't have any instance, the compiler throws an error.
If you try test (*) then you won't get any error, for the same reason that I mentioned above.

Confused about functional composition in Haskell

I know that (.) f g x = f (g x). Suppose f has type Int -> Int, g has type Int -> Int -> Int. Now let h be defined by h x y = f (g x y). Which of the following statements are true and why (why not)?
a. h = f . g
b. h x = f . (g x)
c. h x y = (f . g) x y
Supposedly, only b. is true, while the others are false. I would think a. and b. are equivalent... a. is saying two functions are equal. Two functions are equal only iff when I add an argument to the end of both sides, it will still be equal. So I get h x = f . g x. Now (.) is an operator, so functional application takes precedence over it, so f . g x = f . (g x), which is b.
This looks like a homework, so I won't give the answer of which one is correct.
You consider a and b as identical incorrectly. If f . g is applied to x, you get (from the definition of (.))
(f . g) x = f (g x)
But b is f . (g x), which doesn't expand to f (g x). If you follow b through using the definition of (.), you will see the sense in the comments of the others.
Function composition's initial definition is a bit confusing, so I'll write it a different way:
f . g = \a -> f (g a)
This means that f . g returns a function which first applies the argument to g, then applies the result of that to f. This is also clear in the type signature:
(.) :: (b -> c) -> (a -> b) -> (a -> c)
Now for your function h, it has a type of something like h :: a -> a -> a. Remember that -> is right-associative, so the type could be written as h :: a -> (a -> a). Essentially, h :: a -> b, though this type would cause an error because b and a are uninferrable. (.) will only allow one argument to be applied to the first function, so:
-- One could write,
h x y = f (g x y)
-- But One could also write
h x = f . g x
-- Or, more clearly:
h x = (f) . (g x)
This is because Haskell functions are curried, so we can apply some arguments to g without fully evaluating it.
If we imagine what would happen if we applied (.) visually, then simplify, we can see how it works:
h x = \a -> f ((g x) a)
h x = \a -> f (g x a)
h x a = f (g x a)
So yes, b is the answer. This is because (.) only allows one argument to be applied to the first function before moving to the next.
Now you're job can be tackling the other incorrect solutions by simplifying as I have. It's not too difficult.