Considering Haskell has currying functions, we can do this:
foo a b = a + b -- equivalent to `foo a = \b -> a + b`
foo 1 -- ok, returns `\b -> 1 + b`
foo 1 2 -- ok, returns 3
Declaring the function returning a lambda, just like in the comment, works just fine as well.
But when I compose these functions, like this:
foo a b = a + b
bar x = x * x
bar . foo 1 -- ok, returns a lambda
bar . foo 1 2 -- wrong, I need to write `(bar . foo 1) 2`
Then it results in an error.
The question is: why are the parentheses around the function composition necessary?
Let's assume that you've define the following in GHCi:
λ> let foo a b = a + b
λ> let bar x = x * x
Based on some of your follow-up comments, it seems that you believe
bar . foo 1 2
to be equivalent to
(bar . foo 1) 2
However, remember that function application (space) has higher precedence than the composition operator (.); therefore
bar . foo 1 2
is really equivalent to
bar . ((foo 1) 2)
Now, let's look at the types:
. has type (b -> c) -> (a -> b) -> a -> c; its two arguments are functions (that can be composed).
bar has type Num a => a -> a, and is therefore compatible with the type (b -> c) of the first argument of ..
foo 1 2 has type Num a => a; it's a (polymorphic) numeric constant, not a function, and is therefore not compatible with the type (a -> b) of the second argument of ..
That's why you're getting a type error in bar . foo 1 2. What you can do, though, is
bar $ foo 1 2
because the $ operator has type (a -> b) -> a -> b. See Haskell: difference between . (dot) and $ (dollar sign)
bar . foo 1 2 is bar . (foo 1 2) not (bar . foo 1) 2
There's nothing mysterious going on here related to lambdas. Say we expanded the application of foo to 1:
bar . foo 1 2
bar . (\b -> 1 + b) 2
Now, we apply the lambda to the 2
bar . 3
And there is your problem.
Conversely, if we place the parentheses correctly, we evaluate it like this:
(bar . foo 1) 2
(bar . (\b -> 1 + b)) 2
(\x -> bar ((\b -> 1 + b) x)) 2
bar 3
Related
I am trying to get my head around in Haskell expressions using $ operator. Specifically on how to write this in Haskell using $ operator or another if required:
add 1 (add (subtract 2 4) (subtract 8 16))
I managed to remove two paren groups as in:
add 1 $ add (subtract 2 4) $ subtract 8 16
But still need to remove the last pair.
Any ideas?
You can try infix form
add 1 $ subtract 2 4 `add` subtract 8 16
EDIT
There is other way.
Lets define:
newtype W a = W { w :: a }
pure' = W
(.$.) :: W (a -> b) -> a -> W b
(.$.) (W a) b = W $ a b
and operation to use for example
plus :: Int -> Int -> Int
plus = (+)
Then we can do next
foo :: Int
foo = w $ pure' plus .$. plus 1 2 .$. 2
It is basically applicative functor (you can google it for examples) just with different names.
You prefix your operation with w $ pure' and separate arguments with .$..
Got this:
data Cmd = PushK Int | Pop | Push Int
deriving (Eq,Show)
type StackProgram = [Cmd]
Question:
How can I access the Int value of PushK?
> head [PushK 5, Pop]
PushK 5 -- Great!
> (\_ x -> x)PushK 5
5 -- Great!
> (\_ x -> x)(head [PushK 5, Pop])
Couldn't match expected type `t1 -> t' with actual type `Cmd'
Anyone have a solution?
You unwrap values out of a data constructor by using pattern matching, or by defining record syntax (in which case Haskell generates the getters itself).
Pattern matching
Since here the type is not defined as record, we thus have to use pattern matching:
getK :: Cmd -> Int
getK (PushK x) = x
-- ...
and probably you need to handle the cases of another data constructor.
We can also perform this pattern matching with a lambda expression:
(\(PushK x) -> x) (PushK 5)
Records
We can also define the command as a record:
data Cmd = PushK { k :: Int } | Pop | Push { p :: Int } deriving (Eq,Show)
Now Haskell has generated two functions k :: Cmd -> Int and p :: Cmd -> Int automatically, so in that case we can write:
k (PushK 5)
which will return 5.
Why did (\_ x -> x) PushK 5 return 5?
In Haskell functions are first class citizens. That means you can pass functions as arguments, return them as result. You here did not constructed a Cmd.
In fact PushK is a data constructor, and a function (with type Int -> Cmd), you thus called the lambda expression with two parameters: the first one is the pushK, and the second is 5. You simply omit the first parameter, and retun the second x.
But it is thus derived as:
(\y x -> x) PushK 5
= ((\y -> (\x -> x)) PushK) 5 -- (more verbose version)
-> (\x -> x) 5
-> 5
You may want to define a single catamorphism to deconstruct an arbitrary Cmd value.
cmdCata :: (Int -> a) -- Function to apply to x in (PushK x)
-> a -- Value to replace Pop
-> (Int -> a) -- Function to apply to x in (Push x)
-> Cmd -- The value to deconstruct
-> a -- The result
cmdCata f _ _ (PushK x) = f x
cmdCata _ x _ Pop = x
cmdCata _ _ f (Push x) = f x
It takes two functions and a default value (for Pop) to turn any Cmd value into a value of type a. The following extracts the value wrapped by PushK or Push and rewraps it with Just (the function for PushK doing a little extra work just to show the difference between PushK and Push), and replaces Pop with Nothing.
> cmdCata (Just . (+3)) Nothing Just (PushK 5)
Just 8 -- 5 + 3
> cmdCata (Just . (+3)) Nothing Just Pop
Nothing
> cmdCata (Just . (+3)) Nothing Just (Push 20)
Just 20
Or if you just want an integer and a default value for Pop is fine:
> cmdCata id 0 id (PushK 5)
5
> cmdCata id 0 id Pop
0
> cmdcata id 0 id (Push 3)
3
Compare cmdCata to Data.Maybe.maybe, and think of what functions analogous to Data.Maybe.fromJust, Data.Maybe.catMaybes, etc, could be defined for your Cmd type.
I have a class defined like this, so that foo takes a generic type and returns an Integer:
class Foo a where
foo :: a -> Integer
and a couple of instances defined so it will work with Bool and Char types:
instance Foo Bool where
foo _ = 10
instance Foo Char where
foo _ = 20
If I now want to add an instance for a list with a generic type, I would want to do something like this:
instance Foo [a] where
foo (t:ts) = (foo t) + (foo ts)
However, this is wrong. From my current understanding, I would want to assume that Haskell infers the types and does something like this:
foo [False,True] -> foo False + foo True -> 10 + 10 = 20
I've looked at several books and read about polymorphism and typeclasses, including Learn You a Haskell For Great Good! but still can't wrap my head around how to solve this?
You need to say that the list must contain Foo values:
instance Foo a => Foo [a] where
foo (h:t) = foo h + foo t
foo [] = 0
You can only call foo h when h is a Foo instance, so you need to qualify the type class for [a] so that it only works for lists of Foo instances.
Otherwise, if, for instance, you had a [Int], foo h would imply that you'd try to call foo on an Int value, but foo isn't defined for that type.
With the above implementation for [a] you get expected results:
Prelude> foo [True,False,True]
30
Prelude> foo [True,False,True,True]
40
Prelude> foo "foo"
60
You forgot the base case:
instance Foo a => Foo [a] where
foo (t:ts) = foo t + foo ts
foo [] = 0
Mind that the call foo ts does not mean that we call foo on the second element. We actually call recursively the function we define (the foo in boldface), and this will thus keep calling foo on the elements of the list, until the list is exhausted, in which case the base case foo [] = 0 will be used.
So it will evaluate:
foo (False : True : [])
-> foo False + foo (True : [])
-> 20 + foo (True : [])
-> 20 + foo True + foo []
-> 20 + 20 + foo []
-> 20 + 20 + 0
-> 20 + 20
-> 40
->
When I have the two functions:
a)
three :: Int -> Maybe Int
three a
| a == 3 = Just 3
| otherwise = Nothing
b)
takeOne :: Int -> Int
takeOne a = (a - 1)
how do I call function a as a parameter to function b? i.e How do I let function b accept a 'Maybe Int' in place of an 'Int'?
At the minute when I try
takeOne (three 3)
I get the error:
ERROR - Type error in application
*** Expression : takeThree (three 3)
*** Term : three 3
*** Type : Maybe Int
*** Does not match : Int
Thanks.
You've got a few options, but I'd say the easiest is fmap:
fmap :: Functor f => (a -> b) -> f a -> f b
Example:
> fmap takeOne $ three 3
Just 2
> fmap takeOne $ three 2
Nothing
Another option would be to use the function maybe, which takes a default value, a function to apply to any value inside the Just, and then the Maybe a to apply this to. An example should make it clear
> maybe 0 takeOne $ three 3
2
> maybe 0 takeOne $ three 2
0
Another alternative if you just want to give a default value is to use the function fromMaybe from Data.Maybe:
> import Data.Maybe
> fromMaybe 0 $ three 3
3
> fromMaybe 0 $ three 2
0
In Haskell, there is a typeclass called Functor defined as
class Functor f where
fmap :: (a -> b) -> f a -> f b
There are many, many types that are instances of Functor. In fact, all parametrized data structures are Functors, as are all Applicatives and Monads. The easiest mental model of a Functor is that it's just a fancy name for a container. For lists, fmap = map, for example. All it does is map a function over the elements inside a container.
Some more examples are:
> fmap (+1) (Left "error")
Left "error"
> fmap (+1) (Right 1)
Right 2
> x <- fmap (++", world") getLine
Hello
> x
Hello, world
> fmap (+1) [1..5]
[2,3,4,5,6]
> fmap (+1) ("fst", 2)
("fst", 3)
Even functions are Functors! Here fmap = (.), it's just normal function composition:
> let lengthPlusOne = fmap (+1) length
> lengthPlusOne "Hello"
6
One other option of course is to write your own.
data IAcceptedAMaybeInt = GotAnswer Int | NothingAtTheMoment deriving Show
pleaseAcceptAMaybeInt f g a = case g a of
Just b -> GotAnswer (f b)
otherwise -> NothingAtTheMoment
Output:
*Main> pleaseAcceptAMaybeInt takeOne three 3
GotAnswer 2
*Main> pleaseAcceptAMaybeInt takeOne three 2
NothingAtTheMoment
Is it possible in Haskell to implement a function which returns its own function name?
A possible type could be (a -> b) -> String.
You want a function that takes a function argument, and returns the definition site variable name that corresponds to the name of that function?
This isn't possibly without meta-programming, which is usually a sign you're doing something wrong :).
But assuming you're not, one way to achieve something in the right direction is via Template Haskell, which can get at unique names (how the compiler names things). E.g.
Prelude Language.Haskell.TH> :set -XTemplateHaskell
Prelude Language.Haskell.TH> let f x y = x + y
Prelude Language.Haskell.TH> $( stringE . show =<< reify 'f )
"VarI f_1627394057
(ForallT [PlainTV a_1627394063]
[ClassP GHC.Num.Num [VarT a_1627394063]]
(AppT (AppT ArrowT (VarT a_1627394063))
(AppT (AppT ArrowT (VarT a_1627394063))
(VarT a_1627394063))))
Nothing (Fixity 9 InfixL)"
And now we know a lot about the variable. So you can play games by passing a Name to the function (via 'f) rather than f itself.
You are certainly in the world of reflection and meta-programming though, so it would help to know more about what you are trying to do.
To clarify something mentioned in dons' post: no functions have names in Haskell. There are bindings which may bind functions, but if I had such a function (call it getName) as you seek then what would you expect this to return:
let f x = x
g = f
h = f
in getName g == getName h
I don't know what you need it for, but maybe a simplistic solution suffices? Like so:
data NamedFunction a b = NamedFunction {
name :: String,
apply :: a -> b
}
timesTwo :: NamedFunction Int Int
timesTwo = NamedFunction "timesTwo" (\x -> 2 * x)
which you can use as follows:
ghci> timesTwo `apply` 7
14
ghci> name timesTwo
"timesTwo"
You can then write your own version of (.):
-- contrast (.) :: (b -> c) -> (a -> b) -> (a -> c)
compose :: NamedFunction b c -> NamedFunction a b -> NamedFunction a c
compose (NamedFunction n1 f1) (NamedFunction n2 f2) =
NamedFunction (n1++ " . " ++ n2) (f1 . f2)
In ghci:
ghci> let f = timesTwo `compose` timesTwo in (f `apply` 7, name f)
(28,"timesTwo . timesTwo")
You'll have to reimplement your own versions of map, filter and so on, and you're bound to run into other problems later, but maybe this is all you need...
Am I missing something? This function returns its own function name.
Prelude> let myNameIs::(a->b) -> String; myNameIs f = "myNameIs"
Prelude> :type myNameIs
myNameIs :: (a -> b) -> String
Prelude> myNameIs myNameIs
"myNameIs"
You can preprocess your source code with CPP. In CPP
#define _NAMEOF(name) #name
defines a macro, _NAMEOF, for stringifying text (including surrounding it with programmer's quotation marks). You can then use it as follows:
head [] = error $ _NAMEOF(head) ++ ": empty list!"
which CPP should translate into a valid Haskell source code line:
head [] = error $ "head" ++ ": empty list!"