Is there a way I can create a function with multiple definitions for different patterns including one that is executed when no of the other function's statements patterns are matched?
E.g.:
someFunc (pattern1) = def1
someFunc (pattern2) = def2
someFunc (<otherwise/all other possible values>) = def3
Or if this is not possible, how can it be achieved?
Thanks in advance!
Best regards,
Skyfe.
You can use the wildcard match _:
isJust :: Maybe a -> Bool
-- Here we don't care about what's inside the `Just`
isJust (Just _) = True
-- Here we don't care what it is, it's not a `Just` so return `False`
isJust _ = False
For clarification, patterns are tried in the order you define them, so the above function is not equivalent to
isJust _ = False
isJust (Just _) = True
because the _ pattern is matched first. What the compiler is actually doing is turning this into a case statement internally, so the first function would be equivalent to
isJust x = case x of
Just _ -> True
_ -> False
and as we know from every other programming language that has ever existed, case statements are tried in order.
Related
My teacher recently went over a function in ML that uses "let" & "in" but the body of the function is confusing to me as I dont understand how they work together to produce the result. The function takes a list of vegetables in your garden and replaces an original vegetable with a given substitute, so that list will print out the substitute in every location where the original element is in.This is the function
image to function code
fun replaceVegetable(orig, subt, Garden([]) = Garden([])
| replaceVegetable(orig, subt, Garden([first::rest]) =
let val Garden(newRest) =
replaceVegetable(orig, subst, Garden(rest));
in Garden((if first = orig then subst else first)::newRest)
end
| replaceVegetable(orig, subst, x) = x;
Im not worried about the last pattern "replaceVegetable(orig, subst, x) = x;", im mainly concerned about understanding the second pattern. I think I understand that Garden(newRest) is a local variable to the function and that whatever replaceVegetable(orig, subst, Garden(rest)) produces will be stored in that local variable. I dont exactly know what happens on "in Garden((if first = orig then subst else first)::newRest)" is this applying recursion so it can run through the list I give it to see where it has to replace the original with the substitute? If so, I can't exactly see how its doing that as the function as a whole is confusing for me to look at.
let, in, and end go together; in Garden((if first ... is not a "unit of language" and doesn't mean anything.
In the simpler form,
let val x = y in e end
means "in the expression 'e', 'x' has the same value as 'y'.
If the function took just a plain list, it might be easier to understand:
fun replaceVegetable(orig, subst, []) = []
| replaceVegetable(orig, subst, first::rest) =
let val newRest =
replaceVegetable(orig, subst, rest)
in (if first = orig then subst else first)::newRest
end
| replaceVegetable(orig, subst, x) = x;
The second case here is exactly the same as
| replaceVegetable(orig, subst, first::rest) =
(if first = orig then subst else first)::(replaceVegetable(orig, subst, rest))
Your function also has a pattern-matching binding instead of a plain variable binding.
let val Garden newRest = replaceVegetable(...)
in ...
end
matches on the result of the recursion and binds the "wrapped" list to newRest.
It means exactly the same as
case replaceVegetable (...) of
Garden newRest => ...
[...] a pair of functions tofun : int -> ('a -> 'a) and fromfun : ('a -> 'a) ->
int such that (fromfun o tofun) n evaluates to n for every n : int.
Anyone able to explain to me what this is actually asking for? I'm looking for more of an explanation of that than an actual solution to this.
What this is asking for is:
1) A higher-order function tofun which when given an integer returns a polymorphic function, one which has type 'a->'a, meaning that it can be applied to values of any type, returning a value of the same type. An example of such a function is:
- fun id x = x;
val id = fn : 'a -> 'a
for example, id "cat" = "cat" and id () = (). The later value is of type unit, which is a type with only 1 value. Note that there is only 1 total function from unit to unit (namely, id or something equivalent). This underscores the difficulty with coming up with defining tofun: it returns a function of type 'a -> 'a, and other than the identity function it is hard to think of other functions. On the other hand -- such functions can fail to terminate or can raise an error and still have type 'a -> 'a.
2) fromfun is supposed to take a function of type 'a ->'a and return an integer. So e.g. fromfun id might evaluate to 0 (or if you want to get tricky it might never terminate or it might raise an error)
3) These are supposed to be inverses of each other so that, e.g. fromfun (tofun 5) needs to evaluate to 5.
Intuitively, this should be impossible in a sufficiently pure functional language. If it is possible in SML, my guess is that it would be by using some of the impure features of SML (which allow for side effects) to violate referential transparency. Or, the trick might involve raising and handling errors (which is also an impure feature of SML). If you find an answer which works in SML it would be interesting to see if it could be translated to the annoyingly pure functional language Haskell. My guess is that it wouldn't translate.
You can devise the following property:
fun prop_inverse f g n = (f o g) n = n
And with definitions for tofun and fromfun,
fun tofun n = ...
fun fromfun f = ...
You can test that they uphold the property:
val prop_test_1 =
List.all
(fn i => prop_inverse fromfun tofun i handle _ => false)
[0, ~1, 1, valOf Int.maxInt, valOf Int.minInt]
And as John suggests, those functions must be impure. I'd also go with exceptions.
For all the progress I've made in F#, I still get lost in various of the constructor and deconstructor syntax.
I'm running a recursive simulation. One of the parameters is a function for the stopping condition. I have various possible stopping conditions to choose from. I make them all have the same signature. So I decide it would be nice, and educational, to lock down these functions to a custom type--so that not just any function that happens to match the signature can be sent:
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
I think I'm doing this right, from tutorials, having a type name and an identical constructor name (confusing...), for a single case discriminated union. But now I can't figure out how to apply this type to an actual function:
let Condition1 lastRet nextRet i fl =
true
How do I make Condition1 be of type StoppingCondition? I bet it's trivial. But I've tried putting StoppingCondition as the first, second or last term after let, with and without parens and colons. And everything is an error.
Thanks for the patience found here.
EDIT:
I'll try to synthesize what I lean from the four answers (as of this moment), all good:
Trying to mimic this pattern:
s : string = "abc"
I was trying to write:
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
let condition1 lastRet nextRet i fl : StoppingCondition = // BAD
//wrong for a type alias, totally wrong for a union constructor
true
//or
let condition1 : StoppingCondition lastRet nextRet i fl = // BAD again
true
or other insertions of : Stopping Condition (trying to prefix it, in the way that constructors go, in that one line).
Now I see that to get what I was getting at I would have to do:
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
let conditionFunc1 lastRet nextRet i fl = //...
true
let stoppingCondition1 = StoppingCondition conditionFunc1
//or
let stoppingCondition2 = StoppingCondition <| (func lastRet nextRet i fl -> false)
//and there's another variation or 2 below
And what I didn't appreciate as a big negative to this approach is how a union type is different from a type alias. A type alias of string admits of the string functions when declared--it really is a string and does "string things. A single case discriminated union of string--is not a string any more. To have it do "string things" you have to unwrap it. (Or write versions of those functions into your type (which might be wrappers of the string functions).) Likewise a type alias of my function accepts those parameters. A DU of my function is just a wrapper and doesn't take arguments. So this doesn't work with discriminated union:
let x = stoppingCondition1 ret1 ret2 2 3.0 // BAD
//"stoppingCondition1 is not a function and cannot be applied"
And there's not enough value in my case here to work around the wrapper. But a type alias works:
type StoppingAlias = ReturnType -> ReturnType -> int -> float -> bool
let stoppingCondition:StoppingAlias = fun prevRet nextRet i x -> true
let b = stoppingCondition ret1 ret2 10 1.0 // b = true
I may not have everything straight in what I just said, but I think I'm a lot closer.
Edit 2:
Side note. My question is about defining the type of a function. And it compares using a type alias and a union type. As I worked at trying to do these, I also learned this about using a type alias:
This works (from: https://fsharpforfunandprofit.com/posts/defining-functions/ ):
type Adder = decimal -> decimal -> decimal
let f1 : Adder = (fun x y -> x + y)
//or
let f2 : decimal -> decimal -> decimal = fun x y -> x + y
but these are wrong:
let (f2 : Adder) x y = x + y // bad
let (f3 x y) : (decimal -> decimal -> decimal) = x + y // bad
let (f3 : (decimal -> decimal -> decimal)) x y = x + y // bad
And some discussion on this whole issue: F# Type declaration possible ala Haskell?
(And also, yeah, "assigning a type" isn't the right thing to say either.)
You don't "make it be of type" StoppingCondition. You declare a value of type StoppingCondition and pass Condition1 as the parameter of the DU case constructor:
let stop = StoppingCondition Condition1
That means, however, that every time you want to access the function contained in your single DU case, you have to pattern match over it in some way; that can become annoying.
You say you don't want just any functions that fulfill the signature to be valid as stopping conditions; however, it seems to be specific enough to avoid "accidentally" passing in an "inappropriate" function - with that, you could do something simpler - define StoppingCondition as a type alias for your specific function type:
type StoppingCondition = ReturnType -> ReturnType -> int -> float -> bool
Now you can use StoppingCondition everywhere you need to specify the type, and the actual values you pass/return can be any functions that fulfill the signature ReturnType -> ReturnType -> int -> float -> bool.
As has been said, you have to construct an instance of a StoppingCondition from an appropriate function, for example:
let Condition1 = StoppingCondition (fun _ _ _ _ -> true)`
One nice way to do this without weird indentation or extra parentheses is a backward pipe:
let Condition1 = StoppingCondition <| fun lastRet nextRet i fl ->
// Add function code here
The signature might be long enough to justify a record type instead of four curried parameters. It's a question of style and how it'll be used; the result may look like this:
type MyInput =
{ LastReturn : ReturnType
NextReturn : ReturnType
MyInt : int
MyFloat : float }
type StopCondition = StopCondition of (MyInput -> bool)
let impossibleCondition = StopCondition (fun _ -> false)
let moreComplicatedCondition = StopCondition <| fun inp ->
inp.MyInt < int (round inp.MyFloat)
To call the function inside a StopCondition, unwrap it with a pattern:
let testStopCondition (StopCondition c) input = c input
Specify the return type of a function is done like this:
let Condition1 lastRet nextRet i fl :StoppingCondition=
true
of course, this won't compile as true is not of the correct type.
I suspect the actual definition you want is closer to
let Condition1 :StoppingCondition=
true
though, as the type looks like it contains the function arguments.
Expanding on this, you can define such a function like:
let Condition1=fun a b c d -> StoppingCondition(fun a b c d -> whatever)
but this whole thing is pretty ugly.
Realistically, I think it is better to put all the functions in an array, which will force the types to match
So, it seems to me that you things you might want to with StoppingConditions are to create some predefined type of stopping condition.
Here are some examples of some possible stopping conditions:
let stopWhenNextGreaterThanLast = StoppingCondition (fun last next _ _ -> next > last)
let stopWhenLastGreaterThanLast = StoppingCondition (fun last next _ _ -> last> next)
(I've underscored the parameters I'm not using in my stopping condition definition)
Hopefully you can see that both of these values of type StoppingCondition.
Then you might want a function to determine if the stopping condition had been met given some parameters:
let shouldStop stoppingCond last next i value =
match stoppingCond with
|StoppingCondition f -> f last next i value
This function takes a stopping condition and the various states of your recursion and returns true or false depending on whether or not it should now stop.
This should be all you need to make use of this approach in practice.
You could extend this approach by doing something like this to cover multiple potential stopping conditions:
type StoppingCondition =
| StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
| Or of StoppingCondition * StoppingCondition
And modifying the shouldStop function
let rec shouldStop stoppingCond last next i value =
match stoppingCond with
|StoppingCondition f -> f last next i value
|Or (stp1, stp2) -> (shouldStop stp1 last next i value) || (shouldStop stp2 last next i value)
Now if we have a single condition, we stop when it's met or if we multiple conditions, we can check whether either of them are met.
Then you could Or together new stopping conditions from a base condition:
let stopWhenIIsEven = StoppingCondition (fun _ _ i _ -> i % 2 = 0)
let stopWhenValueIsZero = StoppingCondition (fun _ _ _ value -> value = 0.0)
let stopWhenIEvenOrValueZero = Or (stopWhenIIsEven, stopWhenValueIsZero)
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"
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]