I wonder if there is any way that I can make SML print each recursion out? I am having problem with a function I wrote and that would be very helpful!
I am using Emacs if it matters.
Thanks!
You can have several expressions in a row in sml by putting semicolons between them and surrounding the entire thing with parentheses, like this:
(exp1;exp2;exp3)
The result of the last expression is the only one that is kept - the others are just thrown away. However, you can have an expression with side effects, such as print, and then the thing you actually want to do after.
fun useless x = (print "Hey, there\n";x+2)
Do you mean something like this?
fun annotatedFold _ y [] = (print "base case\n"; y)
| annotatedFold f y (x :: xs) = (print "recursive case\n"; annotatedFold (f x y) xs)
(Although, in all honesty, I would try to put the printing logic in f, if possible)
Related
I have a problem, OCaml thinks the a and s parameters of my function are unit lists, but they have to be 'a list and string respectively. The function has to output the list elements separated by the given separator.
The result has to be a string, with the below input: "This-is-label"
P.S. I know about match, but I can`t use it
let rec function1 a s =
if a = [] then failwith "Empty list" else
if List.tl a = [] then List.hd a else
if List.tl a != [] then List.hd a; s; function1 List.tl a s
;;
function1 ["This"; "is"; "label"] "-";;
It seems you expect this expression to be a string:
List.hd a; s; function1 List.tl a s
However, the meaning of the ; operator is to evaluate the expression at the left and then ignore its value. (It is also considered bad form if the type isn't unit.) Then evaluate the expression at the right, which is the value of the expression.
So this expression says to evaluate List.hd a, then forget the value. Then evaluate s, then forget the value. Then evaluate the recursive call.
So the first problem is to assemble these things into a string.
The ^ operator concatenates two strings. So something like this is closer to what you want:
List.hd a ^ s ^ function1 (List.tl a) s
Note that you need to parenthesize the call to List.tl. Otherwise it looks like two separate parameters to function1.
The problem in your code are missing () around List.tl a in the recursive call. Also ^ must be used to concatenate the strings instead of ;. The code is still very un-ocaml like.
There really is no good way to do this without pattern matching. If this is a homework assignment where you aren't allowed to use pattern matching then please give your instructor a big kick in the behind.
The order of arguments also would be better the other way around, have the separator as first argument. That way you can bind the function to a separator and reuse it many times.
Two alternative implementations:
let rec join s = function
| [] -> "" (* or failwith "Empty list" if you insist *)
| [x] -> x
| x::xs -> x ^ s ^ join s xs
let join s a =
let (res, _) =
List.fold_left
(fun (acc, sep) x -> (x ^ sep ^ acc, s))
("", "")
a
in
res
I try to define function with the following protocol:
[(1,2), (6,5), (9,10)] -> [3, 11, 19]
Here is what I have now:
fun sum_pairs (l : (int * int) list) =
if null l
then []
else (#1 hd(l)) + (#2 hd(l))::sum_pairs(tl(l))
According to type checker I have some type mismatch, but I can't figure out where exactly I'm wrong.
This code runs in PolyML 5.2:
fun sum_pairs (l : (int * int) list) =
if null l
then []
else ((#1 (hd l)) + (#2 (hd l))) :: sum_pairs(tl l)
(* ------------^-------------^ *)
The difference from yours is subtle, but significant: (#1 hd(l)) is different from (#1 (hd l)); the former doesn't do what you think - it attempts to extract the first tuple field of hd, which is a function!
While we're at it, why don't we attempt to rewrite the function to make it a bit more idiomatic? For starters, we can eliminate the if expression and the clunky tuple extraction by matching on the argument in the function head, like so:
fun sum_pairs [] = []
| sum_pairs ((a, b)::rest) = (a + b)::sum_pairs(rest)
We've split the function into two clauses, the first one matching the empty list (the recursive base case), and the second one matching a nonempty list. As you can see, this significantly simplified the function and, in my opinion, made it considerably easier to read.
As it turns out, applying a function to the elements of a list to generate a new list is an incredibly common pattern. The basis library provides a builtin function called map to aid us in this task:
fun sum_pairs l = map (fn (a, b) => a + b) l
Here I'm using an anonymous function to add the pairs together. But we can do even better! By exploiting currying we can simply define the function as:
val sum_pairs = map (fn (a, b) => a + b)
The function map is curried so that applying it to a function returns a new function that accepts a list - in this case, a list of integer pairs.
But wait a minute! It looks like this anonymous function is just applying the addition operator to its arguments! Indeed it is. Let's get rid of that too:
val sum_pairs = map op+
Here, op+ denotes a builtin function that applies the addition operator, much like our function literal (above) did.
Edit: Answers to the follow-up questions:
What about arguments types. It looks like you've completely eliminate argument list in the function definition (header). Is it true or I've missed something?
Usually the compiler is able to infer the types from context. For instance, given the following function:
fun add (a, b) = a + b
The compiler can easily infer the type int * int -> int, as the arguments are involved in an addition (if you want real, you have to say so).
Could you explain what is happening here sum_pairs ((a, b)::rest) = (a + b)::sum_pairs(rest). Sorry for may be dummy question, but I just want to fully understand it. Especially what = means in this context and what order of evaluation of this expression?
Here we're defining a function in two clauses. The first clause, sum_pairs [] = [], matches an empty list and returns an empty list. The second one, sum_pairs ((a, b)::rest) = ..., matches a list beginning with a pair. When you're new to functional programming, this might look like magic. But to illustrate what's going on, we could rewrite the clausal definition using case, as follows:
fun sum_pairs l =
case l of
[] => []
| ((a, b)::rest) => (a + b)::sum_pairs(rest)
The clauses will be tried in order, until one matches. If no clause matches, a Match expression is raised. For example, if you omitted the first clause, the function would always fail because l will eventually be the empty list (either it's empty from the beginning, or we've recursed all the way to the end).
As for the equals sign, it means the same thing as in any other function definition. It separates the arguments of the function from the function body. As for evaluation order, the most important observation is that sum_pairs(rest) must happen before the cons (::), so the function is not tail recursive.
Alright, so I was making some tests to get familiar with Scala, and wanted to see if I could make lists Java style rather than the fancy way you'd do it in Scala...
I know that you can do it like this: val lst = List.range(0, 100, 1) but I just wanted to see what java style would look like in scala
Alright so here's what I did:
var lst = List[Int]()
for(i <- 0 until 100) {
lst = lst :: i // here's where it complains
}
for some reason scala, or at least the scala ide for eclipse doesn't like that I append using infix notation, a-la lst :: i it wants me to do it like this: lst.::(i) otherwise it says :: isn't defined or something, it's not the first time it's happened either...
so can anyone here explain why it does that, or is it just a case of bad implementation in eclipse and thus something I have to live with
This isn't a problem with infix notation. Rather, it's because method names ending with : are applied as
a ??: b
b.??:(a)
So you simply have your arguments backwards.
lst = i :: lst
will work fine.
(Of course, you then have the issue that lists act like stacks, so you need to push the numbers on in reverse order.)
In Scala, a List is of immutable length. It can work like a LIFO (last in, first out) structure, but it cannot behave like a Java ArrayList.
You are doing this:
val lst = List[Int]()
which gives your lst a size of 0. It means you can't really do anything with it.
For a mutable collection, use ListBuffer.
Also, the :: operator is right associative, which means it will be called on the object found on the right side of the operator.
val lst = ListBuffer[Int]()
for (i <- 0 until 100) {
lst += i // will add to the tail.
}
I sometimes find myself writing code like this:
someFunc :: Foo -> Int
someFunc foo = length $ do
x <- someList
guard someGuard
return ()
Or equivalently:
someFunc foo = length [() | x <- someList, someGuard]
Is there a better way to perform this sort of computation? More efficient? More readable? More idiomatic?
Primo
guard someGuard
return ()
is redundant, guard already returns () if the condition is true. Then I suppose someGuard actually depends on x, otherwise it would be if someGuard then length someList else 0. The usual way to write it is
someFunc foo = filter (\x -> someGuard) someList
if the situation is really as simple as your example looks. For more complicated situations, using one of your example styles is the most direct way. I find the do-notation preferable if things get really complicated.
If you find yourself repeatedly programming to a pattern, the thing to do is write a higher-order function to encapsulate that pattern. You could use the body you have, but in order to be utterly confident that your code is not allocating, I would recommend to use foldl and strict application of an increment operator:
numberSatisfying :: Integral n => (a -> Bool) -> [a] -> n
numberSatisfying p = foldl (\n x -> if p x then (+1) $! n else n) 0
I have used QuickCheck to confirm this code equivalent to your original code. (And yes, it is pretty cool that QuickCheck will test with random predicates.)
Looking for a built-in function that will do the following:
mklist x = [x]
The benefit is that I can use it in a composition to create a list of one element. Understand that (replicate 1) is available but is there a more direct function? Would be useful in situations like this:
["Alice", "Bob", "Charlie"] >>= mklist . ("Hello " ++)
Monadic return:
return x
Or:
(:[]) x
It's less characters, but more shift-key usage, so might be harder to type.