Suppose I have a function that takes 3 parameters as input. How to partially apply this function in Elm so it takes first and last parameters and waits for the second parameter to return the final result?
This can be done in Ramda with R.__ which is named placeholer.
You can just wrap it in a lambda function that has the shape you want, which is what would be produced by any other means anyway:
\y -> f "x" y "z"
In a curried language I find the need to do this so rare that adding syntax sugar specifically for this use case seems unnecessary.
As glennsl says, you can wrap your function in another function with the argument order that you want. his answer assumes that you know statically what the first and third arguments are, if you don't, but just want to partially apply the first and third argument, then apply the second you can take a function like,
joinThree : String -> String -> String -> String
joinThree first second third =
first ++ second ++ third
and wrap it in a new function that calls the first function, but with a different argument order,
joinThreeWrapper : String -> String -> String -> String
joinThreeWrapper first third second =
joinThree first second third
This allows you to call this function like,
welcomeToNeverland : String -> String
welcomeToNeverland name =
let
myGreeting = joinThreeWrapper "Welcome " " to Neverland"
in
myGreeting name
Then you can use it like,
text (welcomeToNeverland "Wendy")
-- Welcome Wendy to Neverland
Writing joinThreeWrapper like this makes it a bit easier to map your function over a list like,
greetMany : List String -> List String
greetMany names =
List.map (joinThreeWrapper "Welcome " ", this is our town. ") names
so that you can do,
text (List.map (++) (greetMany ["Jesse", "Carl"]))
-- Welcome Jesse, this is our town. Welcome Carl, this is our town.
You can use flip from the core Basics module.
For instance:
> append3 x y z = x ++ y ++ z
<function> : appendable -> appendable -> appendable -> appendable
> hello = flip (append3 "Hello, ") "!"
<function> : String -> String
> hello "world"
"Hello, world!" : String
Related
we are currently sitting on a task from university, which we don't fully understand (please no solution but only ideas or suggestions).
What is given is a type:
type MyType = String -> String
Now we are trying to be able to have a function, which takes 2 Strings and a function (the type) and then gives a function (type)
myCode :: String -> String -> MyType -> MyType
and we already implemented a function, which can be used as MyType one:
emptyString :: MyType
emptyString :: (\a -> "")
The task is to be able to store several 2x Strings. This is our current idea:
myCode :: String -> String -> MyType ->MyType
myCode a b c = (\x -> b)
in this case we have an input String, which is "Hello" and another one which is "World" and then as c we put in the "emptyString".
This works for one String, because when we type the following in the console:
a = (myCode "Hello" "World" emptyString) ""
we get "World" on input "a". Now the hard part: We should be able to store several of these (searching them is another task, not needed right now). We thought we might be able to use "a" now when declaring another variable:
b = (myCode "1" "2" a) "Hello" "World" emptyString "")
This would call in "b" the function saved as "a" and within this the "emptyString".
As you may have guessed - it doesn't work! And we are really at a loss on how to carry on from now.
When you reached this part, it means you took the time to understand our complicated explanation of our task - thanks a lot.
Thanks for suggestions and help in advance!
From the question linked by amalloy in the comments, it looks like you are trying to build a phonebook based on a continuation passing style like paradigm.
Basically, what is supposed to happen for your type
myCode :: String -> String -> MyType -> MyType
is that you will generate a piece of data dat = myCode a b pb, which is of type MyType. So, you can query dat with an s :: String and it will output another String. In the operation of dat s, if you expand it to the definition,
dat s = myCode a b pb s
you have access to three strings, a, b, and whatever pb s returns. You will build up functionality recursively, either by doing something with a b and s, or pushing it down the road to pb, letting the continuation handle it.
Hope this helps without giving too much away.
I'm learning F# and I cannot figure out what the difference between let, fun and function is, and my text book doesn't really explain that either. As an example:
let s sym = function
| V x -> Map.containsKey x sym
| A(f, es) -> Map.containsKey f sym && List.forall (s sym) es;;
Couldn't I have written this without the function keyword? Or could I have written that with fun instead of function? And why do I have to write let when I've seen some examples where you write
fun s x =
...
What's the difference really?
I guess you should really ask MSDN, but in a nutshell:
let binds a value with a symbol. The value can be a plain type like an int or a string, but it can also be a function. In FP functions are values and can be treated in the same way as those types.
fun is a keyword that introduces an anonymous function - think lambda expression if you're familiar with C#.
Those are the two important ones, in the sense that all the others usages you've seen can be thought as syntax sugar for those two. So to define a function, you can say something like this:
let myFunction =
fun firstArg secondArg ->
someOperation firstArg secondArg
And that's very clear way of saying it. You declare that you have a function and then bind it to the myFunction symbol.
But you can save yourself some typing by just conflating anonymous function declaration and binding it to a symbol with let:
let myFunction firstArg secondArg =
someOperation firstArg secondArg
What function does is a bit trickier - you combine an anonymous single-argument function declaration with a match expression, by matching on an implicit argument. So these two are equivalent:
let myFunction firstArg secondArg =
match secondArg with
| "foo" -> firstArg
| x -> x
let myFunction firstArg = function
| "foo" -> firstArg
| x -> x
If you're just starting on F#, I'd steer clear of that one. It has its uses (mainly for providing succinct higher order functions for maps/filters etc.), but results in code less readable at a glance.
These things are sort of shortcuts to each other.
The most fundamental thing is let. This keyword gives names to stuff:
let name = "stuff"
Speaking more technically, the let keyword defines an identifier and binds it to a value:
let identifier = "value"
After this, you can use words name and identifier in your program, and the compiler will know what they mean. Without the let, there wouldn't be a way to name stuff, and you'd have to always write all your stuff inline, instead of referring to chunks of it by name.
Now, values come in different flavors. There are strings "some string", there are integer numbers 42, floating point numbers 5.3, Boolean values true, and so on. One special kind of value is function. Functions are also values, in most respects similar to strings and numbers. But how do you write a function? To write a string, you use double quotes, but what about function?
Well, to write a function, you use the special word fun:
let squareFn = fun x -> x*x
Here, I used the let keyword to define an identifier squareFn, and bind that identifier to a value of the function kind. Now I can use the word squareFn in my program, and the compiler will know that whenever I use it I mean a function fun x -> x*x.
This syntax is technically sufficient, but not always convenient to write. So in order to make it shorter, the let binding takes an extra responsibility upon itself and provides a shorter way to write the above:
let squareFn x = x*x
That should do it for let vs fun.
Now, the function keyword is just a short form for fun + match. Writing function is equivalent to writing fun x -> match x with, period.
For example, the following three definitions are equivalent:
let f = fun x ->
match x with
| 0 -> "Zero"
| _ -> "Not zero"
let f x = // Using the extra convenient form of "let", as discussed above
match x with
| 0 -> "Zero"
| _ -> "Not zero"
let f = function // Using "function" instead of "fun" + "match"
| 0 -> "Zero"
| _ -> "Not zero"
I have the following function definitions (which are equivalent):
reverseWords :: String -> String
reverseWords wds = unwords . map reverse . words $ wds
and
reverseWords :: String -> String
reverseWords = unwords . map reverse . words
I understand that they are equivalent as they yield the same result but I'm a bit confused about the second form.
If I call a function like:
reverseWords abc
How does haskell decide where to place this 'abc' parameter?
Haskell does not need to decide where to place abc. When you call reverseWords in your second example it will simply return unwords . map reverse . words.
And then abc gets applied to that with which you will end up with the same result as in your first example.
This is also called Point-free style as you can read more about it here: https://wiki.haskell.org/Point-free
I want to create a custom field in Yesod that is a text field with a JSON array of doubles. However I keep getting type errors. My current attempt is:
doubleListField :: RenderMessage master FormMessage => Field sub master [Double]
doubleListField = Field
{ fieldParse = parseHelper $ Right . decodeUtf8 . parse json
, fieldView = \theId name attrs val isReq -> toWidget [hamlet|
$newline never
<input id="#{theId}" name="#{name}" *{attrs} type="number" :isReq:required="" value="Hey">
|]
}
(Correct whitespace found: https://gist.github.com/4394850)
I'm currently failing with:
Couldn't match expected type `Data.ByteString.Internal.ByteString'
with actual type `[Text]
-> m0 (Either (SomeMessage master0) (Maybe Text))'
In the second argument of `($)', namely `parseHelper $ Right'
In the `fieldParse' field of a record
In the expression:
Field
{fieldParse = parse json $ parseHelper $ Right,
fieldView = \ theId name attrs val isReq
-> toWidget (\ _render_a5Cg -> ...)}
fieldView I'll modify and I know how to go about that but I'm flummoxed about how fieldParse should look. Thanks!
Please note that your code does not match the error.
The fieldParse function should turn the user submitted data into a Haskell structure. As you discovered, there is a parseHelper function that simplifies creating the field.
The type of parseHelper is essentially (Text -> Either FormMessage a) -> X, where X is the exact type of fieldParse. That is, once you pass one argument to the helper, you get a correct fieldParse.
The argument to parseHelper should be a function, that recieves a Text input and returns Right [Double] or Left FormMessage if parsing failed.
Depending on what you use to parse the JSON, the function could look like this (assuming existence of a few more helpers that you will most likely have to write):
fieldParse = parseHelper $ \text -> case parse json text of
Right value | isListOfDoubles value -> Right $ extractListOfDoubles value
_ -> Left "Wrong input"
If I want to add a space at the end of a character to return a list, how would I accomplish this with partial application if I am passing no arguments?
Also would the type be?
space :: Char -> [Char]
I'm having trouble adding a space at the end due to a 'parse error' by using the ++ and the : operators.
What I have so far is:
space :: Char -> [Char]
space = ++ ' '
Any help would be much appreciated! Thanks
Doing what you want is so common in Haskell it's got its own syntax, but being Haskell, it's extraordinarily lightweight. For example, this works:
space :: Char -> [Char]
space = (:" ")
so you weren't far off a correct solution. ([Char] is the same as String. " " is the string containing the character ' '.) Let's look at using a similar function first to get the hang of it. There's a function in a library called equalFilePath :: FilePath -> FilePath -> Bool, which is used to test whether two filenames or folder names represent the same thing. (This solves the problem that on unix, mydir isn't the same as MyDir, but on Windows it is.) Perhaps I want to check a list to see if it's got the file I want:
isMyBestFile :: FilePath -> Bool
isMyBestFile fp = equalFilePath "MyBestFile.txt" fp
but since functions gobble their first argument first, then return a new function to gobble the next, etc, I can write that shorter as
isMyBestFile = equalFilePath "MyBestFile.txt"
This works because equalFilePath "MyBestFile.txt" is itself a function that takes one argument: it's type is FilePath -> Bool. This is partial application, and it's super-useful. Maybe I don't want to bother writing a seperate isMyBestFile function, but want to check whether any of my list has it:
hasMyBestFile :: [FilePath] -> Bool
hasMyBestFile fps = any (equalFilePath "MyBestFile.txt") fps
or just the partially applied version again:
hasMyBestFile = any (equalFilePath "MyBestFile.txt")
Notice how I need to put brackets round equalFilePath "MyBestFile.txt", because if I wrote any equalFilePath "MyBestFile.txt", then filter would try and use just equalFilePath without the "MyBestFile.txt", because functions gobble their first argument first. any :: (a -> Bool) -> [a] -> Bool
Now some functions are infix operators - taking their arguments from before and after, like == or <. In Haskell these are just regular functions, not hard-wired into the compiler (but have precedence and associativity rules specified). What if I was a unix user who never heard of equalFilePath and didn't care about the portability problem it solves, then I would probably want to do
hasMyBestFile = any ("MyBestFile.txt" ==)
and it would work, just the same, because == is a regular function. When you do that with an operator function, it's called an operator section.
It can work at the front or the back:
hasMyBestFile = any (== "MyBestFile.txt")
and you can do it with any operator you like:
hassmalls = any (< 5)
and a handy operator for lists is :. : takes an element on the left and a list on the right, making a new list of the two after each other, so 'Y':"es" gives you "Yes". (Secretly, "Yes" is actually just shorthand for 'Y':'e':'s':[] because : is a constructor/elemental-combiner-of-values, but that's not relevant here.) Using : we can define
space c = c:" "
and we can get rid of the c as usual
space = (:" ")
which hopefully make more sense to you now.
What you want here is an operator section. For that, you'll need to surround the application with parentheses, i.e.
space = (: " ")
which is syntactic sugar for
space = (\x -> x : " ")
(++) won't work here because it expects a string as the first argument, compare:
(:) :: a -> [a] -> [a]
(++) :: [a] -> [a] -> [a]