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 => ...
Related
what's the best way to turn a Right[List] into a List
I will parse a Json String like so
val parsed_states = io.circe.parser.decode[List[List[String]]](source)
And that will create an value equivalent to this
val example_data = Right(List(List("NAME", "state"), List("Alabama", "01"), List("Alaska", "02"), List("Arizona", "04")))
I'm trying to grok Right, Left, Either and implement the best way to get a list of StateName, StateValue pairs out of that list above.
I see that any of these ways will give me what I need (while dropping the header):
val parsed_states = example_data.toSeq(0).tail
val parsed_states = example_data.getOrElse(<ProbUseNoneHere>).iterator.to(Seq).tail
val parsed_states = example_data.getOrElse(<ProbUseNoneHere>).asInstanceOf[Seq[List[String]]].tail
I guess I'm wondering if I should do it one way or another based on the possible behavior upstream coming out of io.circe.parser.decode or am I overthinking this. I'm new to the Right, Left, Either paradigm and not finding terribly many helpful examples.
in reply to #slouc
trying to connect the dots from your answer as they apply to this use case. so something like this?
def blackBox: String => Either[Exception, List[List[String]]] = (url:String) => {
if (url == "passalong") {
Right(List(List("NAME", "state"), List("Alabama", "01"), List("Alaska", "02"), List("Arizona", "04")))
}
else Left(new Exception(s"This didn't work bc blackbox didn't parse ${url}"))
}
//val seed = "passalong"
val seed = "notgonnawork"
val xx: Either[Exception, List[List[String]]] = blackBox(seed)
def ff(i: List[List[String]]) = i.tail
val yy = xx.map(ff)
val zz = xx.fold(
_ => throw new Exception("<need info here>"),
i => i.tail)
The trick is in not getting state name / state value pairs out of the Either. They should be kept inside. If you want to, you can transform the Either type into something else (e.g. an Option by discarding whatever you possibly had on the left side), but don't destroy the effect. Something should be there to show that decoding could have failed; it can be an Either, Option, Try, etc. Eventually you will process left and right case accordingly, but this should happen as late as possible.
Let's take the following trivial example:
val x: Either[String, Int] = Right(42)
def f(i: Int) = i + 1
You might argue that you need to get the 42 out of the Right so that you can pass it to f. But that's not correct. Let's rewrite the example:
val x: Either[String, Int] = someFunction()
Now what? We have no idea whether we have a Left or a Right in value x, so we can't "get it out". Which integer would you obtain in case it's a Left? (if you really do have an integer value to use in that case, that's fair enough, and I will address that use case a bit later)
What you need to do instead is keep the effect (in this case Either), and you need to continue working in the context of that effect. It's there to show that there was a point in your program (in this case someFunction(), or decoding in your original question) that might have gone wrong.
So if you want to apply f to your potential integer, you need to map the effect with it (we can do that because Either is a functor, but that's a detail which probably exceeds the scope of this answer):
val x: Either[String, Int] = Right(42)
def f(i: Int) = i + 1
val y = x.map(value => f(value)) // Right(43)
val y = x.map(f) // shorter, point-free notation
and
val x: Either[String, Int] = someFunction()
def f(i: Int) = i + 1
// either a Left with some String, or a Right with some integer increased by 1
val y = x.map(f)
Then, at the very end of the chain of computations, you can handle the Left and Right cases; for example, if you were processing an HTTP request, then in case of Left you might return a 500, and in case of Right return a 200.
To address the use case with default value mentioned earlier - if you really want to do that, get rid of the Left and in that case resolve into some value (e.g. 0), then you can use fold:
def f(i: Int) = i + 1
// if x = Left, then z = 0
// if x = Right, then z = x + 1
val z = x.fold(_ => 0, i => i + 1)
Is it possible in F# to apply a value as though it is a function? For example:
let record =
{|
Func = fun x -> x * x
Message = "hello"
|}
let message = record.Message // unsweetened field access
let unsweet = record.Func 3 // unsweetened function application
let sweet = record 3 // sweetened function application
Right now, the last line doesn't compile, of course:
error FS0003: This value is not a function and cannot be applied.
Is there some sort of syntactical sweetener that would allow me to "route" function application as I see fit, while still retaining its normal unsweetened behavior as well? I'm thinking of something magic like this:
// magically apply a record as though it was a function
let () record arg =
record.Func arg
(Note: I used a record in this example, but I'd be happy with a class as well.)
The closest thing I can think of would be a custom operator using statically resolved type parameters to resolve a specific property of type FSharpFunc, then invoke the function with the supplied input parameter. Something like this:
let record =
{|
Func = fun x -> x * x
Message = "hello"
|}
let inline (>.>) (r: ^a) v =
let f = (^a : (member Func: FSharpFunc< ^b, ^c>) r)
f v
record >.> 3 // val it : int = 9
Ok here goes...
I have been experimenting on various examples of declaring functions with "self" in the parameters.
I don't have full understanding of this which is what I'm trying to fully understand. I'm a complete beginner, but I am compelled to grasp this fully.
The 2 examples below return the same results, although in example 2, if I don't declare "self = {}" within the function, I need to place "self" (or the ":") in the function parameters for it to work. Is this the whole deal with "self"?
Are there other implications when using "self"?
Example 1
function Character.new(x)
self = {}
self.name = x
return self.name
end
a = Character
b = Character
hobbit = a.new ("Frodo")
dragon = b.new ("Smaug")
print (hobbit)
print (dragon)
Example 2
Character = {}
function Character:new(x)
self.name = x
return self.name
end
a = Character
b = Character
hobbit = a:new ("Frodo")
dragon = b:new ("Smaug")
print (hobbit)
print (dragon)
;^)
Zalokin
You're using global variables when you should be creating instances.
Try these lines instead, they may help you understand:
-- example 1
print (hobbit)
print(self.name)
print (dragon)
print(self.name)
and
-- example 2
print (hobbit)
print(Character.name)
print (dragon)
print(Character.name)
: lets you access the table which includes the function from within the function without an explicit (first argument) pass. It can be used both when defining and calling a function.
The example below contains a table t. The table has 3 functions (a,b and c) and a string entry under the key greeting.
All the function/method calls print the same string "hello user".
Notice how you can still call a method (a function which has its container table as the first argument) the same way as a normal function, but you have to explicitly pass the table as the first argument.
The self argument can be called what ever you want and you can still call the function with a : as long as you use the correct argument name inside the function (not self in this case). The function c serves as an example of that.
It is basically just syntax sugar.
local t = {}
t.greeting = "hello"
function t:a(name)
print(self.greeting, name)
end
function t.b(self, name)
print(self.greeting, name)
end
function t.c(myself, name)
print(myself.greeting, name)
end
t.a(t, "user")
t:a("user")
t.b(t, "user")
t:b("user")
t.c(t, "user")
t:c("user")
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"
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.