If I have a list of functions, each of the type a -> a for some type, what is the most shortest, elegant and idiomatic way to combine them; preferably without adding extra dependencies?
Some variants include
foo (x:xs) = x . (foo xs)
foo [] = id
and
foo = foldr (.) id
and
foo = appEndo . mconcat . map Endo
but for some reason Iām expecting to find something nicer.
I'd say you're not going to beat
comp = foldr (.) id
Why? Well we have a list of things and we're trying to reduce it in a right associative way.
If you look at the implementations of and, sum, maximum and similar, you'll see that this is how they're implemented in the standard library, I don't think you get more idiomatic than that :)
Tangent: I hesitate to add the foldr1 variant mentioned in comments because I'd say that it's unexpected behavior for this to be partial, unlike say maximum where it clearly must be.
Another one, which may not be shorter than foldr (.) id but which I think is cute:
foo = flip (foldr id)
Related
I've started a course on introduction to F#, and I've been having some trouble with two assignments. The first one had me creating two functions, where the first function takes an input and adds it with four, and the second one calculates sqrt(x^2+y^2). Then I should write function expressions for them both, but for some reason it gives me the error "Unexpected symbol'|' in implementation file".
let g = fun n -> n + 4;;
let h = fun (x,y) -> System.Math.Sqrt((x*x)+(y*y));;
let f = fun (x,n) -> float
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
The second assignment asks me to create a function, which finds the sequence of Fibonaccis numbers. I've written the following code, but it seems to forget about the 0 in the beginning since the output always is n+1 and not n.
let rec fib = function
|0 -> 0
|1 -> 1
|n -> fib(n-1) + fib(n-2)
;;
Keep in mind that this is the first week, so I should be able to create these with those methods.
Your first snippet mostly suffers from two issues:
In F#, there is a difference between float and int. You write integer values as 4 or 0 and you write float values as 4.0 or 0.0. F# does not automatically convert integers to floats, so you need to be consistent.
Your syntax in the f function is a bit odd - I'm not sure what float is supposed to mean there and the fun and function constructs behave differently.
So, starting with your original code:
let g = fun n -> n + 4;;
This works, but I would not write it as an explicit function using fun - you can use let to define functions too and it is simpler. Also, you only need ;; in F# Interactive, but if you're using any decent editor with command for sending code to F# interactive (via Alt+Enter) you do not need that.
However, in your f function, you want to return float so you need to modify g to return float too. This means replacing 4 with 4.0:
let g n = n + 4.0
The h function is good, but you can again write it using let:
let h (x,y) = System.Math.Sqrt((x*x)+(y*y));;
In your f function, you can either use function to write a function using pattern matching, or you can use more verbose syntax using match (function is just a shorthand for writing a function and then pattern matching on the input):
let f = function
| (n,0.0) -> g(n)
| (x,n) -> h(x,n)
let f (x, y) =
match (x, y) with
| (n,0.0) -> g(n)
| (x,n) -> h(x,n)
Also note that the indentation matters - you need spaces before |.
I'm going to address your first block of code, and leave the Fibonacci function for later. First I'll repost your code, then I'll talk about it.
let g = fun n -> n + 4;;
let h = fun (x,y) -> System.Math.Sqrt((x*x)+(y*y));;
let f = fun (x,n) -> float
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
First comment: If you're defining a function and assigning it immediately to a name, like in all these examples, you don't need the fun keyword. The usual way to define functions is to write them as let (name) (parameters) = (function body). So your code above would become:
let g n = n + 4;;
let h (x,y) = System.Math.Sqrt((x*x)+(y*y));;
let f (x,n) = float
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
I haven't made any other changes, so your f function still has an error in it. Let's address that error next.
I think the mistake you're making here is to think that fun and function are interchangeable. They're not. fun is standard function definition, but function is something else. It's a very common pattern in F# to write functions like the following:
let someFunc parameter =
match parameter with
| "case 1" -> printfn "Do something"
| "case 2" -> printfn "Do something else"
| _ -> printfn "Default behavior"
The function keyword is shorthand for one parameter plus a match expression. In other words, this:
let someFunc = function
| "case 1" -> printfn "Do something"
| "case 2" -> printfn "Do something else"
| _ -> printfn "Default behavior"
is exactly the same code as this:
let someFunc parameter =
match parameter with
| "case 1" -> printfn "Do something"
| "case 2" -> printfn "Do something else"
| _ -> printfn "Default behavior"
with just one difference. In the version with the function keyword, you don't get to pick the name of the parameter. It gets automatically created by the F# compiler, and since you can't know in advance what the name of the parameter will be, you can't refer to it in your code. (Well, there are ways, but I don't want to make you learn to run before you have learned to walk, so to speak). And one more thing: while you're still learning F#, I strongly recommend that you do NOT use the function keyword. It's really useful once you know what you're doing, but in your early learning stages you should use the more explicit match (parameter) with expressions. That way you'll get used to seeing what it's doing. Once you've been doing F# for a few months, then you can start replacing those let f param = match param with (...) expressions with the shorter let f = function (...). But until match param with (...) has really sunk in and you've understood it, you should continue to type it out explicitly.
So your f function should have looked like:
let f (x,n) =
match (x,n) with
|(n,0) -> g(n)
|(x,n) -> h(x,n);;
I see that while I was typing this, Tomas Petricek posted a response, and it addresses the incorrect usage of float, so I won't duplicate his explanation of why you're going to get an error on the word float in your f function. And he also explained about ;;, so I won't duplicate that either. I'll just say that when he mentions "any decent editor with command for sending code to F# interactive (via Alt+Enter)", there are a lot of editor choices -- but as a beginner, you might just want someone to recommend one to you, so I'll recommend one. First off, though: if you're on Windows, you might be using Visual Studio already, in which case you should stick to Visual Studio since you know it. It's a good editor for F#. But if you don't use Visual Studio yet, I don't recommend downloading it just to play around with F#. It's a beast of a program, designed for professional software developers to do all sorts of things they need to do in their jobs, and so it can feel a bit overwhelming if you're just getting started. So I would actually recommend something more lightweight: the editor called Visual Studio Code. It's cross-platform, and will run perfectly well on Linux, OS X or on Windows. Once you've downloaded and installed VS Code, you'll then want to install the Ionide extension. Ionide is a plugin for VS Code (and also for Atom, though the Atom version of Ionide is updated less often since all the Ionide developers use VS Code now) that makes F# editing a real pleasure. There are actually three extensions you'll find: Ionide-fsharp, Ionide-FAKE, and Ionide-Paket. Download and install all three: FAKE and Paket are two tools for F# programming that you might not need yet, but once you do need them, you'll already have them installed.
Okay, that's enough to get you started, I think.
In working with lenses, I occasionally have the need for some basic text parsing in the chain of optics. In one API I'm dealing with, there is a JSON field like this:
"timespent": "0.25",
Since it is incorrectly encoded as a string instead of a number, I can't just do the typical lens-aeson solution:
v ^? key "timespent" . _Double -- this doesn't work
So, I need this instead:
v ^? key "timespent" . _String . mystery
where the mystery optic needs to turn Text into a Double. I know that mystery could be typed as follows:
mystery :: Prism' Text Double
And I could built this as follows:
mystery = prism' (pack . show) (readMaybe . unpack)
And technically, this function could have an even more general type signature with Read and Show constraints, but that's not really what my question is about. What I don't like is the Prism is really too strong for what I'm doing. Most of the time, I'm interested in parsing but not is rendering it back to a string. So, I need either a Traversal or a Fold but I'm not sure which one, and I'm not sure how to build them. When I look at the type signature of ^? to find the minimum optic required, I see:
(^?) :: s -> Getting (First a) s a -> Maybe a
I can sort of understand what this means but not very well. So, to make my question clear, it is:
If I have a function f :: Text -> Maybe a, how can I turn this into a Traversal or a Fold? Thanks, and let me know if there is anything I can clarify.
I think what you want is a Getter:
_Read :: Read a => Getter Text (Maybe a)
_Read f = contramap g . f . g where g = readMaybe . unpack
In general, if you have x :: a -> b then \f -> contramap x . f . x is a Getter a b.
Then to get the a value out of the Maybe a, use traverse, so combined you have _Read . traverse which is a Read a => Fold Text a.
I am beginner in Haskell .
The convention used in function definition as per my school material is actually as follows
function_name arguments_separated_by_spaces = code_to_do
ex :
f a b c = a * b +c
As a mathematics student I am habituated to use the functions like as follows
function_name(arguments_separated_by_commas) = code_to_do
ex :
f(a,b,c) = a * b + c
Its working in Haskell .
My doubt is whether it works in all cases ?
I mean can i use traditional mathematical convention in Haskell function definition also ?
If wrong , in which specific cases the convention goes wrong ?
Thanks in advance :)
Let's say you want to define a function that computes the square of the hypoteneuse of a right-triangle. Either of the following definitions are valid
hyp1 a b = a * a + b * b
hyp2(a,b) = a * a + b * b
However, they are not the same function! You can tell by looking at their types in GHCI
>> :type hyp1
hyp1 :: Num a => a -> a -> a
>> :type hyp2
hyp2 :: Num a => (a, a) -> a
Taking hyp2 first (and ignoring the Num a => part for now) the type tells you that the function takes a pair (a, a) and returns another a (e.g it might take a pair of integers and return another integer, or a pair of real numbers and return another real number). You use it like this
>> hyp2 (3,4)
25
Notice that the parentheses aren't optional here! They ensure that the argument is of the correct type, a pair of as. If you don't include them, you will get an error (which will probably look really confusing to you now, but rest assured that it will make sense when you've learned about type classes).
Now looking at hyp1 one way to read the type a -> a -> a is it takes two things of type a and returns something else of type a. You use it like this
>> hyp1 3 4
25
Now you will get an error if you do include parentheses!
So the first thing to notice is that the way you use the function has to match the way you defined it. If you define the function with parens, you have to use parens every time you call it. If you don't use parens when you define the function, you can't use them when you call it.
So it seems like there's no reason to prefer one over the other - it's just a matter of taste. But actually I think there is a good reason to prefer one over the other, and you should prefer the style without parentheses. There are three good reasons:
It looks cleaner and makes your code easier to read if you don't have parens cluttering up the page.
You will take a performance hit if you use parens everywhere, because you need to construct and deconstruct a pair every time you use the function (although the compiler may optimize this away - I'm not sure).
You want to get the benefits of currying, aka partially applied functions*.
The last point is a little subtle. Recall that I said that one way to understand a function of type a -> a -> a is that it takes two things of type a, and returns another a. But there's another way to read that type, which is a -> (a -> a). That means exactly the same thing, since the -> operator is right-associative in Haskell. The interpretation is that the function takes a single a, and returns a function of type a -> a. This allows you to just provide the first argument to the function, and apply the second argument later, for example
>> let f = hyp1 3
>> f 4
25
This is practically useful in a wide variety of situations. For example, the map functions lets you apply some function to every element of a list -
>> :type map
map :: (a -> b) -> [a] -> [b]
Say you have the function (++ "!") which adds a bang to any String. But you have lists of Strings and you'd like them all to end with a bang. No problem! You just partially apply the map function
>> let bang = map (++ "!")
Now bang is a function of type**
>> :type bang
bang :: [String] -> [String]
and you can use it like this
>> bang ["Ready", "Set", "Go"]
["Ready!", "Set!", "Go!"]
Pretty useful!
I hope I've convinced you that the convention used in your school's educational material has some pretty solid reasons for being used. As someone with a math background myself, I can see the appeal of using the more 'traditional' syntax but I hope that as you advance in your programming journey, you'll be able to see the advantages in changing to something that's initially a bit unfamiliar to you.
* Note for pedants - I know that currying and partial application are not exactly the same thing.
** Actually GHCI will tell you the type is bang :: [[Char]] -> [[Char]] but since String is a synonym for [Char] these mean the same thing.
f(a,b,c) = a * b + c
The key difference to understand is that the above function takes a triple and gives the result. What you are actually doing is pattern matching on a triple. The type of the above function is something like this:
(a, a, a) -> a
If you write functions like this:
f a b c = a * b + c
You get automatic curry in the function.
You can write things like this let b = f 3 2 and it will typecheck but the same thing will not work with your initial version. Also, things like currying can help a lot while composing various functions using (.) which again cannot be achieved with the former style unless you are trying to compose triples.
Mathematical notation is not consistent. If all functions were given arguments using (,), you would have to write (+)((*)(a,b),c) to pass a*b and c to function + - of course, a*b is worked out by passing a and b to function *.
It is possible to write everything in tupled form, but it is much harder to define composition. Whereas now you can specify a type a->b to cover for functions of any arity (therefore, you can define composition as a function of type (b->c)->(a->b)->(a->c)), it is much trickier to define functions of arbitrary arity using tuples (now a->b would only mean a function of one argument; you can no longer compose a function of many arguments with a function of many arguments). So, technically possible, but it would need a language feature to make it simple and convenient.
I find it hard to get the intuition about encoding function in data type definition. This is done in the definition of the State and IO types, for e.g.
data State s a = State s -> (a,s)
type IO a = RealWorld -> (a, RealWorld) -- this is type synonym though, not new type
I would like to see a more trivial example to understand its value so I could possibly build on this to have more complex examples. For e.g. say I have a data structure, would that make any sense to encode a function in one of the data constructor.
data Tree = Node Int (Tree) (Tree) (? -> ?) | E
I am not sure what I am trying to do here, but what could be an example of a function that I can encode in such a type? And why would I have to encode it in the type, but not use it as a normal function, I don't know, maybe passed as argument when needed?
Really, functions are just data like anything else.
Prelude> :i (->)
data (->) a b -- Defined in`GHC.Prim'
instance Monad ((->) r) -- Defined in`GHC.Base'
instance Functor ((->) r) -- Defined in`GHC.Base'
This comes out very naturally and without anything conceptually surprising if you consider only functions from, say, Int. I'll give them a strange name: (remember that (->) a b means a->b)
type Array = (->) Int
What? Well, what's the most important operation on an array?
Prelude> :t (Data.Array.!)
(Data.Array.!) :: GHC.Arr.Ix i => GHC.Arr.Array i e -> i -> e
Prelude> :t (Data.Vector.!)
(Data.Vector.!) :: Data.Vector.Vector a -> Int -> a
Let's define something like that for our own array type:
(!) :: Array a -> Int -> a
(!) = ($)
Now we can do
test :: Array String
test 0 = "bla"
test 1 = "foo"
FnArray> test ! 0
"bla"
FnArray> test ! 1
"foo"
FnArray> test ! 2
"*** Exception: :8:5-34: Non-exhaustive patterns in function test
Compare this to
Prelude Data.Vector> let test = fromList ["bla", "foo"]
Prelude Data.Vector> test ! 0
"bla"
Prelude Data.Vector> test ! 1
"foo"
Prelude Data.Vector> test ! 2
"*** Exception: ./Data/Vector/Generic.hs:244 ((!)): index out of bounds (2,2)
Not all that different, right? It's Haskell's enforcement of referential transparency that guarantees us the return values of a function can actually be interpreted as inhabitant values of some container. This is one common way to look at the Functor instance: fmap transform f applies some transformation to the values "included" in f (as result values). This works by simply composing the transformation after the target function:
instance Functor (r ->) where
fmap transform f x = transform $ f x
(though you'd of course better write this simply fmap = (.).)
Now, what's a bit more confusing is that the (->) type constructor has one more type argument: the argument type. Let's focus on that by defining
{-# LANGUAGE TypeOperators #-}
newtype (:<-) a b = BackFunc (b->a)
To get some feel for it:
show' :: Show a => String :<- a
show' = BackFunc show
i.e. it's really just function arrows written the other way around.
Is (:<-) Int some sort of container, similarly to how (->) Int resembles an array? Not quite. We can't define instance Functor (a :<-). Yet, mathematically speaking, (a :<-) is a functor, but of a different kind: a contravariant functor.
instance Contravariant (a :<-) where
contramap transform (BackFunc f) = BackFunc $ f . transform
"Ordinary" functors OTOH are covariant functors. The naming is rather easy to understand if you compare directly:
fmap :: Functor f => (a->b) -> f a->f b
contramap :: Contravariant f => (b->a) -> f a->f b
While contravariant functors aren't nearly as commonly used as covariant ones, you can use them in much the same way when reasoning about data flow etc.. When using functions in data fields, it's really covariant vs. contravariant you should foremostly think about, not functions vs. values ā because really, there is nothing special about functions compared to "static values" in a purely functional language.
About your Tree type
I don't think this data type could be made something really useful, but we can do something stupid with a similar type that may illustrate the points I made above:
data Tree' = Node Int (Bool -> Tree) | E
That is, disconsidering performance, isomorphic to the usual
data Tree = Node Int Tree Tree | E
Why? Well, Bool -> Tree is similar to Array Tree, except we don't use Ints for indexing but Bools. And there are only two evaluatable boolean values. Arrays with fixed size 2 are usually called tuples. And with Bool->Tree ā
(Tree, Tree) we have Node Int (Bool->Tree) ā
Node Int Tree Tree.
Admittedly this isn't all that interesting. With functions from a fixed domain the isomorphism are usually obvious. The interesting cases are polymorphic on the function domain and/or codomain, which always leads to somewhat abstract results such as the state monad. But even in those cases, you can remember that nothing really seperates functions from other data types in Haskell.
You generally start FP learning with 2 concepts - data types and functions. Once you have good confidence level of designing programs using these 2 concepts I would suggest you start using only 1 concept i.e of types which means:
You define new types by combining the existing types or type constructors in the language.
You define new type constructors to abstract out a general concept in your problem domain.
Function is a just a type which maps a particular type to another type. Which basically means that the types which the functions maps could themselves be functions and so on (because we just said that functions are type). This is what people generally call higher oreder functions and also this gives you the illusion that a function takes multiple parameters, whereas reality is that a function type always map a type to another type (i.e it is a unary function), but we know that the another type can itself be a function type.
Example : add :: Int -> Int -> Int is same as add :: Int -> (Int -> Int). add is (function) type which maps an Integer to a (function) type which maps an Integer to an Integer.
To create a Function type we use the (->) type constructor provided by Haskell.
Thinking in terms of above points you will find that the line between data types and functions is no more there.
As far as which type to choose is concerned, it solely depends on the problem domain you are trying to solve. Basically, when ever there is a need where you find that you need some sort of mapping from one type to another, you will use the (->) type.
The State is defined using function type because the way we represent state in FP is "a mapping which takes current state and returns a value and new state", as you can see that there is a mapping happening here and hence the use of (->) type.
Let's see if this helps. Unfortunately for beginners, the definition of State quotes State both on the left and right hand side, but they have different meaning: one is the name of the type, the other is the name of the constructor. So the definition is really:
data State s a = St (s -> (a,s))
Which means you can construct a value of type State s a using constructor St and passing it a function from s to (a,s), that is, a function that can construct a value of some type a and a value of next state s from the previous state. This is a simple way to represent a state transition.
In order to see why passing a function is useful, you need to study how the rest of it works. For example, we can construct new value of type State s a given two other values by composing the functions. By composing such States, such state transition functions, you get a state machine, which then can be used to compute a value and final state, given an initial state.
runStateMachine :: State s a -> s -> (a,s)
runStateMachine (St f) x = f x -- or shorter, runStateMachine (St f) = f -- just unwrap the function from the constructor
I need a function with following attributes.
(c->d)->(a->b->c)->a->b->d
my function:
funktionD = (.) . (.)
but :t funktionD
funktionD :: (a -> b) -> (c -> d -> a) -> c -> d -> b
ist this equal?
It is. Type variables--written in lowercase--are just that, variables. You can rename them all you like as long as the pattern of which are the same variable stays the same.
Furthermore, for essentially the same reason, for the type signature you gave there is only one possible function of that type (excluding functions that crash or go into infinite loops, that is). Something to think about!
I think it is. Replace a with c (and vice versa), then replace b with d (and vice versa) and they are the same.