Creating monads in haskell - haskell

I want to create my own monad. This is what i wrote:
data LeafConType a = LeafCon (a,Int,Int)
instance Monad (LeafConType ) where
return = LeafCon
lc#(LeafCon (t,i,n)) >>= f = if i>=n
then lc
else f (t,i,n)
But this dont work. Ghc says:
leafcon.hs:26:1:
Occurs check: cannot construct the infinite type: a = (a, Int, Int)
When generalising the type(s) for `return'
In the instance declaration for `Monad LeafConType'
leafcon.hs:27:1:
Occurs check: cannot construct the infinite type: a = (a, Int, Int)
When generalising the type(s) for `>>='
In the instance declaration for `Monad LeafConType'
Whats wrong with that?
I want to do calculations while i is lower than n. n should be constants by I don't know yet how to do this correct. It should be some mix of State and Maybe. If you have some advices feel free to share it with me:P

About return:
Prelude> :t return
return :: (Monad m) => a -> m a
So return takes an argument of type a, and returns something of type m a. In this case m is LeafConType, so LeafConType a is returned.
Now suppose that we pass True. Then a = Bool, so the return type must be LeafConType Bool. However, you define:
return = LeafCon
So, return True becomes LeafCon True. But that is not allowed, because the type definition of LeafConType states that
data LeafConType a = LeafCon (a, Int, Int)
So for LeafConType Bool the argument to LeafCon must have type (Bool, Int, Int), not just Bool. And that is what the compile error means: a cannot be the same as (a, Int, Int). You state:
I want to do calculations while i is lower than n.
This means that you will need some default values for i and n, for otherwise it will be impossible to define return. If both of them are zero by default, then you could define:
return a = LeafCon (a, 0, 0)
About (>>=):
Prelude> :t (>>=)
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b
Now look at your implementation (slightly different notation, same idea):
lc#(LeafCon (t, i, n)) >>= f | i >= n = lc
| otherwise = f t
What we see here, is that lc is returned when i >= n. But lc is of type LeafConType a, while f is a function which may return a value of type LeafConType b, for any b. As a result it could be that b is not equal to a and hence these types don't match. In conclusion, you seriously have to ask yourself one question:
Can this type of computation be expressed as a monad anyway?

The functions you specified for >>= and return don't satisfy the types required by Monad:
return :: a -> LeafConType a
Given the declaration
return = LeafCon
you give the function the incompatible type
return :: (a, Int, Int) -> LeafConType a
A statement like return 42 would therefore be impossible in your monad.
I don't understand what your monad should do at all.
First take a look at simple, working monads!
instance Monad [] where
(>>=) = concatMap
return a = [a]
instance Monad Maybe where
return = Just
(Just x) >>= f = f x
Nothing >>= f = Nothing

Judging from your description of what you want your monad to do, I think you want something a bit like this:
data LeafConType a = LeafCon { runLeafCon' :: Int -> Int -> (Maybe a, Int, Int) }
runLeafCon :: Int -> Int -> LeafConType a -> Maybe a
runLeafCon i n lc = let (t, _, _) = runLeafCon' lc i n in t
getI :: LeafConType Int
getI = LeafCon $ \i n -> (Just i, i, n)
getN :: LeafConType Int
getN = LeafCon $ \i n -> (Just n, i, n)
setI :: Int -> LeafConType ()
setI i = LeafCon $ \_ n -> (Just (), i, n)
setN :: Int -> LeafConType ()
setN n = LeafCon $ \i _ -> (Just (), i, n)
instance Monad LeafConType where
return t = LeafCon $ \i n -> if (i < n)
then (Just t, i, n)
else (Nothing, i, n)
(LeafCon k) >>= f =
LeafCon $ \i n ->
let (t, i', n') = k i n
in case t of
Nothing -> (Nothing, i', n')
(Just t') -> if (i' < n')
then runLeafCon' (f t') i' n'
else (Nothing, i, n)
example :: Int -> LeafConType ((), Int)
example x = do
i <- getI
m <- setI (i + x)
return (m, i + x)
Some examples:
*Main> runLeafCon 2 10 $ example 4
Just ((),6)
*Main> runLeafCon 2 10 $ example 8
Nothing
*Main> runLeafCon 2 10 $ example 7
Just ((),9)
I threw this together pretty quickly, it's rather ugly, and I haven't checked to see whether it obeys any of the Monad laws, so use at your peril! :)

Related

Getting specific values from a function returned from a monad I.E. the first Int from: "Int -> (a, Int, [Int])"

Thank you kind internet person(s) for your time.
I am attempting to implement a Monad that has type Int -> (a, Int, [Int]) and I need to be able to pull each of those values from the Monad.
Currently I am trying to implement, fmap, return, get, and put. The problem is that I have no idea how to retrieve the values from the Int -> (a, Int, [Int]) type.
The monad's type is defined as newtype M a = M { run :: Int -> (a, Int, [Int]) }
where the first int is the value that kicks off the computation (Like the Collatz sequence), the a is the result, the Int in the tuple is the final state (it will end up at 1 if doing the Collatz sequence), and the list of Ints is a log of all the computations that led up to the final state (I.E. is would be: [5, 16, 8, 4, 2, 1] if the beginning int was 5)
So far I have found ways to retrieve the values in the tuple
newtype M a = M { run :: Int -> (a, Int, [Int]) }
getVals :: M a -> Int -> a
getVals m z = a where
(a, _, _) = run m z
getState :: M a -> Int -> Int
getState m z = mid where
(_, mid, _) = run m z
getLog :: M a -> Int -> [Int]
getLog m z = ws where
(_, _, ws) = run m z
(The z is supposed to be the initial integer value that will kick of the computation: E.G. a collatz sequence)
but I haven't been able to retrieve the initial Int from the Int -> (a, Int, [Int])
Just to clarify I am asking for how to retrieve individual details from a Int -> (a, Int, [Int]) type. The Monad stuff is just the context.
First, a stylistic point: you should redefine your tuple as a data type with named fields:
data MD a = MD {
mValue :: a,
mState :: Int,
mLog :: [Int]}
Now on to the meat.
The general form of a monadic action like this is
myAction :: M a
myAction = M $ \oldState ->
... stuff ...
MD result newState newLogs
The lambda argument oldState is the Int you are looking for.
Your getState looks like this:
getState :: M Int
getState = M $ \s -> MD s s []
So you are returning the state argument as your result, and also passing it on unchanged to the next action. No logs get written as a result of doing this.
You can't write getLog to inspect the current log in this monad because the log list is not being passed along as part of the state. However you can write one which takes an M action, runs it, and gives you the resulting log as well as writing it to the outer log.
getLog :: M a -> M ([Int], a)
getLog action = M $ \oldState ->
let MD result newState innerLog = run action oldState
in MD (innerLog, result) newState innerLog
You will also want an action
writeLog :: Int -> M ()
Your bind >>= will have the type:
(>>=) :: M a -> (a -> M b) -> M b
So your Monad instance is going to start
instance Monad M where
v >>= f = M $ \oldState ->
The new log is going to be the log taken from v concatenated with the log taken from the output of f. The rest is left as an exercise for the reader.
There's only one way (up to equivalence) that any type can be made into a Functor. Here it is for your type:
instance Functor M where
fmap f m = M $ \z -> let (a, mid, ws) = run m z in (f a, mid, ws)
As for how to "retrieve" the Int to the left of the ->, that's not something that's stored in the type. You instead get access to it when the function eventually gets called. For example, in my above instance, you'd access it as the z variable.

How to derive a state monad from first principles?

I am trying to come up with an implementation of State Monad derived from examples of function composition. Here I what I came up with:
First deriving the concept of Monad:
data Maybe' a = Nothing' | Just' a deriving Show
sqrt' :: (Floating a, Ord a) => a -> Maybe' a
sqrt' x = if x < 0 then Nothing' else Just' (sqrt x)
inv' :: (Floating a, Ord a) => a -> Maybe' a
inv' x = if x == 0 then Nothing' else Just' (1/x)
log' :: (Floating a, Ord a) => a -> Maybe' a
log' x = if x == 0 then Nothing' else Just' (log x)
We can have function that composes these functions as follows:
sqrtInvLog' :: (Floating a, Ord a) => a -> Maybe' a
sqrtInvLog' x = case (sqrt' x) of
Nothing' -> Nothing'
(Just' y) -> case (inv' y) of
Nothing' -> Nothing'
(Just' z) -> log' z
This could be simplified by factoring out the case statement and function application:
fMaybe' :: (Maybe' a) -> (a -> Maybe' b) -> Maybe' b
fMaybe' Nothing' _ = Nothing'
fMaybe' (Just' x) f = f x
-- Applying fMaybe' =>
sqrtInvLog'' :: (Floating a, Ord a) => a -> Maybe' a
sqrtInvLog'' x = (sqrt' x) `fMaybe'` (inv') `fMaybe'` (log')`
Now we can generalize the concept to any type, instead of just Maybe' by defining a Monad =>
class Monad' m where
bind' :: m a -> (a -> m b) -> m b
return' :: a -> m a
instance Monad' Maybe' where
bind' Nothing' _ = Nothing'
bind' (Just' x) f = f x
return' x = Just' x
Using Monad' implementation, sqrtInvLog'' can be written as:
sqrtInvLog''' :: (Floating a, Ord a) => a -> Maybe' a
sqrtInvLog''' x = (sqrt' x) \bind'` (inv') `bind'` (log')`
Trying to apply the concept to maintain state, I defined something as shown below:
data St a s = St (a,s) deriving Show
sqrtLogInvSt' :: (Floating a, Ord a) => St a a -> St (Maybe' a) a
sqrtLogInvSt' (St (x,s)) = case (sqrt' x) of
Nothing' -> St (Nothing', s)
(Just' y) -> case (log' y) of
Nothing' -> St (Nothing', s+y)
(Just' z) -> St (inv' z, s+y+z)
It is not possible to define a monad using the above definition as bind needs to be defined as taking in a single type "m a".
Second attempt based on Haskell's definition of State Monad:
newtype State s a = State { runState :: s -> (a, s) }
First attempt to define function that is built using composed functions and maintains state:
fex1 :: Int->State Int Int
fex1 x = State { runState = \s->(r,(s+r)) } where r = x `mod` 2`
fex2 :: Int->State Int Int
fex2 x = State { runState = \s-> (r,s+r)} where r = x * 5
A composed function:
fex3 x = (runState (fex2 y)) st where (st, y) = (runState (fex1 x)) 0
But the definition newtype State s a = State { runState :: s -> (a, s) } does not fit the pattern of m a -> (a -> m b) -> m b of bind
An attempt could be made as follows:
instance Monad' (State s) where
bind' st f = undefined
return' x = State { runState = \s -> (x,s) }
bind' is undefined above becuase I did not know how I would implement it.
I could derive why monads are useful and apply it the first example (Maybe') but cannot seem to apply it to State. It will be useful to understand how I could derive the State Moand using concepts defined above.
Note that I have asked a similar question earlier: Haskell - Unable to define a State monad like function using a Monad like definition but I have expanded here and added more details.
Your composed function fex3 has the wrong type:
fex3 :: Int -> (Int, Int)
Unlike with your sqrtInvLog' example for Maybe', State does not appear in the type of fex3.
We could define it as
fex3 :: Int -> State Int Int
fex3 x = State { runState = \s ->
let (y, st) = runState (fex1 x) s in
runState (fex2 y) st }
The main difference to your definition is that instead of hardcoding 0 as the initial state, we pass on our own state s.
What if (like in your Maybe example) we wanted to compose three functions? Here I'll just reuse fex2 instead of introducing another intermediate function:
fex4 :: Int -> State Int Int
fex4 x = State { runState = \s ->
let (y, st) = runState (fex1 x) s in
let (z, st') = runState (fex2 y) st in
runState (fex2 z) st' }
SPOILERS:
The generalized version bindState can be extracted as follows:
bindState m f = State { runState = \s ->
let (x, st) = runState m s in
runState (f x) st }
fex3' x = fex1 x `bindState` fex2
fex4' x = fex1 x `bindState` fex2 `bindState` fex2
We can also start with Monad' and types.
The m in the definition of Monad' is applied to one type argument (m a, m b). We can't set m = State because State requires two arguments. On the other hand, partial application is perfectly valid for types: State s a really means (State s) a, so we can set m = State s:
instance Monad' (State s) where
-- return' :: a -> m a (where m = State s)
-- return' :: a -> State s a
return' x = State { runState = \s -> (x,s) }
-- bind' :: m a -> (a -> m b) -> m b (where m = State s)
-- bind' :: State s a -> (a -> State s b) -> State s b
bind' st f =
-- Good so far: we have two arguments
-- st :: State s a
-- f :: a -> State s b
-- We also need a result
-- ... :: State s b
-- It must be a State, so we can start with:
State { runState = \s ->
-- Now we also have
-- s :: s
-- That means we can run st:
let (x, s') = runState st s in
-- runState :: State s a -> s -> (a, s)
-- st :: State s a
-- s :: s
-- x :: a
-- s' :: s
-- Now we have a value of type 'a' that we can pass to f:
-- f x :: State s b
-- We are already in a State { ... } context, so we need
-- to return a (value, state) tuple. We can get that from
-- 'State s b' by using runState again:
runState (f x) s'
}
Have a look to this. Summing and extending a bit.
If you have a function
ta -> tb
and want to add "state" to it, then you should pass that state along, and have
(ta, ts) -> (tb, ts)
You can transform this by currying it:
ta -> ts -> (tb, ts)
If you compare this with the original ta -> tb, we obtain (adding parentheses)
ta -> (ts -> (tb, ts))
Summing up, if a function returns tb from ta (i.e. ta -> tb), a "stateful"
version of it will return (ts -> (tb, ts)) from ta (i.e. ta -> (ts -> (tb, ts)))
Therefore, a "stateful computation" (just one function, or either a chain of functions dealing with state) must return/produce this:
(ts -> (tb, ts))
This is the typical case of a stack of ints.
[Int] is the State
pop :: [Int] -> (Int, [Int]) -- remove top
pop (v:s) -> (v, s)
push :: Int -> [Int] -> (int, [Int]) -- add to the top
push v s -> (v, v:s)
For push, the type of push 5 is the same than type of pop :: [Int] -> (Int, [Int]).
So we would like to combine/join this basic operations to get things as
duplicateTop =
v <- pop
push v
push v
Note that, as desired, duplicateTop :: [Int] -> (Int, [Int])
Now: how to combine two stateful computations to get a new one?
Let's do it (Caution: this definition is not the same that the
used for the bind of monad (>>=) but it is equivalent).
Combine:
f :: ta -> (ts -> (tb, ts))
with
g :: tb -> (ts -> (tc, ts))
to get
h :: ta -> (ts -> (tc, ts))
This is the construction of h (in pseudo-haskell)
h = \a -> ( \s -> (c, s') )
where we have to calculate (c, s') (the rest in the expressions are just parameters a and s). Here it is how:
-- 1. run f using a and s
l1 = f a -- use the parameter a to get the function (ts -> (tb, ts)) returned by f
(b, s1) = l1 s -- use the parameter s to get the pair that l1 returns ( :: (tb, ts) )
-- 2. run g using f output, b and s1
l2 = g b -- use b to get the function (ts -> (tb, ts)) returned by g
(c, s') = l2 s1 -- use s1 to get the pair that l2 returns ( :: (tc, ts) )

Haskell Write Monad for expressions

I am trying to design embedded language, where operations can raise certain flags depending on values. I foresee operation on scalar values as well as on vectors (e.g. map, fold, etc.) My idea is to use Writer Monad to keep track of flags. Simplified example, where actual type is "Int" and flag is raised if any of argument is 0.
import Control.Monad.Identity
import Control.Monad.Writer
import Data.Monoid
type WInt = Writer Any Int
bplus :: Int -> Int -> WInt
bplus a b =
do
tell (Any (a == 0 || b == 0)) ;
return (a+b)
wbplus :: WInt -> WInt -> WInt
wbplus wa wb =
do
a <- wa ;
b <- wb ;
tell (Any (a == 0 || b == 0)) ;
return (a+b)
ex0 = runWriter (bplus 1 2)
ex1 = runWriter (bplus 0 2)
ex2 = runWriter (wbplus (return 1) (return 2))
ex3 = runWriter (wbplus (return 0) (return 2))
ex4 = runWriter (wbplus (wbplus (return 1) (return 2)) (return 2))
ex5 = runWriter (wbplus (wbplus (return 0) (return 2)) (return 2))
ex6 = runWriter (wbplus (wbplus (return 1) (return 2)) (return 0))
I am little unsure what is the best way to implement this. Some questions:
Should I define all operations like I did for bplus or like for wbplus. Laters makes composition easier, it seems. But to use foldM binary operator should have type Int -> Int -> WInt.
What would be the appropriate type for lists: Writer Any [Int] or [Wint]?
Any suggestions or thoughts are appreciated.
You can derive bplus from wbplus and vice versa using the appropriate monadic operations:
import Control.Monad
apM2 :: Monad m => (a -> b -> m c) -> m a -> m b -> m c
apM2 f ma mb = do
a <- ma
b <- mb
f a b
pureM2 :: Monad m => (m a -> m b -> m c) -> a -> b -> m c
pureM2 f a b = f (return a) (return b)
They are inverses of each other, evident from the type signatures of their compositions:
ghci> :t pureM2 . apM2
pureM2 . apM2 :: Monad m => (a -> b -> m c) -> a -> b -> m c
ghci> :t apM2 . pureM2
apM2 . pureM2 :: Monad m => (m a -> m b -> m c) -> m a -> m b -> m c
Now you can define wbplus = apM2 bplus or bplus = pureM2 wbplus. There's no definite answer which one is better, use your taste and judgement. TemplateHaskell goes with the wbplus approach and defines all operations to work with values in the Q monad. See Language.Haskell.TH.Lib.
Regarding [m a] vs m [a], you can only go in one direction (via sequence :: Monad m => [m a] -> m [a]). Would you ever want to go in the opposite direction? Do you care about individual values having their own flags or would you rather annotate the computation as a whole with flags?
The real question is, what is your mental model for this? However, let's think about some consequences of each design choice.
If you choose to represent each value as Writer Any a and have all operations work with it, you can start with a newtype:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Control.Monad.Writer
newtype Value a = Value (Writer Any a)
deriving (Functor, Applicative, Monad)
Now you can define instances of standard type classes for your
values:
instance (Num a, Eq a) => Num (Value a) where
va + vb = do
a <- va
b <- vb
(Value . tell . Any) (b == 0 || a == 0)
return (a + b)
(*) = liftM2 (*)
abs = fmap abs
signum = fmap signum
negate = fmap negate
fromInteger = return . fromInteger
instance Monoid a => Monoid (Value a) where
mempty = pure mempty
mappend = liftM2 mappend
For an EDSL this gives a huge advantage: terseness and syntactic support from the compiler. You can now write getValue (42 + 0) instead of wbplus (pure 42) (pure 0).
If, instead, you don't think about flags as a part of your values and rather see them as an external effect, it's better to go with the alternative approach. But rather than write something like Writer Any [Int], use corresponding classes from mtl: MonadWriter Any m => m [Int].
This way, if you later find out that you need to use other effects, you can easily add them to some (but not all) operations. For example, you might want to raise an error in case of division by zero:
data DivisionByZero = DivisionByZero
divZ :: (MonadError DivisionByZero m, Fractional a, Eq a) => a -> a -> m a
divZ a b
| b == 0 = throwError DivisionByZero
| otherwise = pure (a / b)
plusF :: (MonadWriter Any m, Num a, Eq a) => a -> a -> m a
plusF a b = do
tell (Any (b == 0 || a == 0))
return (a + b)
Now you can use plusF and divZ together within one monad, although they have different effects. If you'll later find yourself in need to integrate with some external library, this flexibility will come in handy.
Now, I didn't give it too much thought, but perhaps you could combine those approaches using something like newtype Value m a = Value { getValue :: m a }. Good luck exploring the design space :)

Haskell: Rigid type variable error when pattern matching bind operator

I'm trying to run this
newtype Test a = Test (Int, a)
instance Monad Test where
Test (_, []) >>= k =
k []
Test (_, a) >>= k =
k a
return a =
Test (0, a)
And I get the error:
Couldn't match expected type `a' with actual type `[t0]'
`a' is a rigid type variable bound by
the type signature for >>= :: Test a -> (a -> Test b) -> Test b
at C:\Users\david.phillips\Documents\code\test.hs:4:5
In the pattern: []
In the pattern: (_, [])
In the pattern: Test (_, [])
I get a similar error when I tried using a case statement instead of 2 versions of >>=.
I'm fairly new to haskell and can't see why this wouldn't work.
Edit: Sorry, it's a bad example. Suppose that the first definition of >>= gave a different output.
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
Monad instances are parameterized over a type variable a. You are essentially claiming that it is not, because in the place of that variable, you have pattern matched on the empty list constructor, [], meaning "a is a list of something." The type of eg. bind could, with explicit quantification, be written:
(>>=) :: forall a. m a -> (a -> m b) -> m b
Your definition cannot possibly hold for ALL a.
As an addition to Sarah's answer, you can actually omit your specific pattern match,
Test (_, []) >>= f = f []
is the same as
Test (_, a) >>= f = f a
So you can really just write this as
Test (_, a) >>= f = f a
return a = (0, a)
Now remember that in addition to have the right types, we're supposed to have that
m >>= return = m
return a >>= f = f a
(a >>= b) >>= c = a >>= (\a' -> b a' >>= c)
This worries me though, as
m = Test (1, 'c')
m >>= return === return 'c' === (0, 'c') /== m
So return is no longer functioning as an identity and you're breaking the 1st monad law. Fixing this would mean return would have to preserve the first element of the tuple, problematic since we don't actually tell it about it.
Naively, let's just clobber the first tuple element that our function returns.
Test (a, b) >>= f = Test (a, snd (f b))
Now
Test (1, 'c') >>= return == Test (1, snd (return 'c')) == Test (1, 'c')
But we're still in trouble,
let f a = Test (1, a)
return a >>= f == Test (0, snd (f a)) == Test (0, a) /== f a
So the trick here is to do what the state monad does
newtype Test a = Test{ unTest :: Int -> (Int, a) }
instance Monad Test where
return a = Test $ \i -> (i, a)
(Test m) >>= f = Test $ \i -> let (i', a) = m i
in unTest (f a) $ i'
Which does satisfy the monad laws*. Happily this already exists in Control.Monad.State.
** modulo seq
Get rid of the first pattern. You are trying to make a separate definition for a specific type, which you can't do. All of the definitions need to be for all types a. If you could violate that, the first pattern would be the same as the second pattern but with a bound to [], so just write:
instance Monad Test where
Test (_, a) >>= k =
k a
return a =
Test (0, a)
Test (0, []) >>= k would then match the >>= pattern, and become k [], exactly the same as what your first pattern is unnecessarily trying to do.

About the function monad

I have some confusion with the function monad. The function monad is defined as follow:
instance Monad ((->) r) where
return x = \_ -> x
h >>= f = \w -> f (h w) w
I tried to play around with it by writing a binding operation:
( (*2) >>= (+10) ) 3
(return 3) :: ((->) Int)
But it caused errors. And I also try to rewrite a function AddStuff into the binding operations.
addStuff = do
a <- (*2)
b <- (+10)
return (a+b)
then convert this function into
addStuff' w = (*2) w >>= (\a ->
(+10) w >>= (\b ->
return (a+b) ))
I check the type of the new function as see
addStuff :: (Monad m, Num (m b), Num b) => m b -> m b
Why is that? How can I fix that?
In addStuff' you write (*2) w and (+10) w. Those are equivalent to w*2 and w+10 respectively. So addStuff' is equivalent to this:
addStuff' w = w*2 >>= \a ->
w+10 >>= \b ->
return (a+b)
Writing it this way should make it obvious that here the left operands to >>= are numbers, not functions. That's why the inferred type is telling you that your function only works for numbers that are monads.
When eliminating do notation the left operand to >>= should be exactly the same as the right operand of <-. Also eliminating do notation does not add any arguments to the function. So the correct rewriting would look like this:
addStuff' = (*2) >>= \a ->
(+10) >>= \b ->
return (a+b)
As to why your earlier pieces of code don't work:
( (*2) >>= (+10) ) 3
The operator >>= has type m a -> (a -> m b) -> m b. For simplicity let's assume that all the numbers in this code have type Int, then your left operand has type Int -> Int or m Int if m is (->) Int. So for some type b the right operand should have type Int -> ((->) Int) b or, more readably, Int -> Int -> b. The type it actually has though is Int -> Int. Therefore your expression is ill-typed.
(return 3) :: ((->) Int)
((->) Int) has kind * -> * - the type of a value must have kind *.
Or to approach this differently: return 3 has type m Int for some m (still assuming that all integer literals have type Int for simplicity). So if m is ((->) Int), the type of return 3 will be ((->) Int) Int or Int -> Int, not ((->) Int).

Resources