I'm new to OCaml,and have just found an on-line OCaml guide, http://try.ocamlpro.com/.
When it comes to lesson 5, I get trapped in some exercises. So, here is the problem:
fix all these let expressions in order to get the expected result at the end:
1.
let xy =
let x = 'x' and let y = 'y' in x ::[y]
2.
let ab =
let a = 'a'
let b = 'B' in Char.lowercase b
in a ::[b]
3.
let up = Char.uppercase in
big_xy = List.map up xy ;
big_ab = List.map up ab ;
big_ab # big_xy
PS:I know how to solve problem 1,and I post it here for the need of problem 3.For Problem 2 and 3,I can see where the problem is,but I can hardly figure out how to fix it.I'm a little confused about the compact "let...in" statement,and there is few resource I can refer to for such problem.
This is a completely wrong OCaml, indeed it is not an OCaml at all))
I'm just trying to guess what was your intention, so in the second code sample you have tried to bind to variables to some character values, then lowercase one of them and create a list of this two values.
Before you can understand, what is wrong with your code, you need to know something about OCaml's grammar.
There're several kinds of binding statements in OCaml, the first one is an expression and has the following pattern:
let «variable-name» = «expr-1» in «expr-2»
This means that you bind the result of evaluating «expr-1» to a «variable-name», so that you can use it inside «expr-2» (and only in «expr-2», it is its scope). «expr-2» can be another binding-expression on its own. Let's take some examples:
let a = 'a' in [a]
or
let a = 'a' in
let b = 'b' in
[a; b]
The second kind of bindings is a so called top-level binding, that is used when you're adding some definition to a module level (or an interactive top-level, that is the same). They look a little bit simplier, but they're not expressions. When I say that something is not an expression, I mean, mostly, that it can't be evaluated to a value. So, they have the following pattern:
let «variable-name» = «expr»
As you can see, there is no in part, only raw binding. You can use this statement to create a global constant, e.g.,
let pi = 4. *. atan 1.
Or, you can use it to bind a function to a name (in other words to write a function definition):
let circle_area radius = pi * radius ** 2.
Of course, inside a function you can use any expressions, including a binding expression:
let area_of_circles radii =
let areas = List.map circle_area radii in
List.fold_left (+.) 0. areas
I would like to note, that there're lots of good tutorials and textbooks, that can help you to learn OCaml very fast. You can find them at the OCaml tag page. I, personally, would suggest you to look at the 'OCaml from the very beginning' book.
Related
I going through some Scala exercises in order to understand better high order functions. I have the following problem, which I cant understand how to solve. I have the following list:
val input = List((1,"a"), (1,"b"), (1,"c"), (2,"d"), (2,"y"), (2,"e"), (3, "u"), (3,"a"), (3,"d"))
I want to create a Map from this list which maps each letter encountered on the input list to a list of all the numbers which were previously in the same tuple as that letter. Example output:
Map(a -> List(1,3), b->List(1), c->List(1), d->List(2,3), y->List(2), e->List(2), u->List(3)
What I have tried so far is:
val output = input.groupBy(_._2)
However this gives as output:
Map(e -> List((2,e)), y -> List((2,y)), u -> List((3,u)), a -> List((1,a), (3,a)), b -> List((1,b)), c -> List((1,c)), d -> List((2,d), (3,d)))
Could someone help me understand how I could go about solving this? I appreciate any help as I am new to functional programming
As #sinanspd said:
input
.groupBy {
case (numer, letter) => letter
} map {
case (key, list) => key -> list.map {
case (number, letter) => number
}
}
// Or equivalently
input.groupBy(_._2).view.mapValues(list => list.map(_._1)).toMap
// Or even simpler if you have access to Scala 2.13
input.groupMap(_._2)(_._1)
Every time you want to transform some collection of values where the transformation is one to one, you just need a map, so in this case, you want to transform the values of the Map returned by the groupBy, which are Lists, and then you want to transform every element of those Lists to just return the first component of the tuple. So it is a map inside another map.
Also, the Scaldoc is your friend. Usually, there are many useful methods, like mapValues or groupMap.
Here is a more detailed explanation of my comment. This is what you need to do:
val output = input.groupBy(_._2).mapValues(_.map(_._1))
It is important to remember in functional programming we love pure functions. Meaning we will not have shady side effects and we like to stick to one function one purpose principle
This allows us to chain these pure functions and reason about them linearly. Why am I telling you this? While your instinct might be to look for or implement a single function to do this, don't
In this case, we first groupBy the key, and then map each value where we take the value List and map it to extract the _._1 of the tuple.
This is the best I could do, to make it sorted too , as I see the other responses are not sorted , maybe someone can improve this too:
import scala.collection.immutable.ListMap
ListMap(input.groupBy(_._2).mapValues(_.map(_._1)).toSeq.sortBy(_._1):_*)
I could not find any size or len function in the official documentation. What is a simple way to find the number of elements in a map created using:
module M = Map.Make(String)
I am looking for something like M.size M.empty : 0.
The function that you're looking for is called cardinal (as in the cardinality of a set).
Example:
module M = Map.Make(String)
let m = M.singleton "x" "y"
let () = Printf.printf "%d\n" (M.cardinal m)
This will print 1, as there is exactly one binding.
hoogle4ocaml ": 'a t -> int$" | grep -i map
Would tell you:
~/.opam/4.05.0/lib/ocaml/map.mli: val cardinal: 'a t -> int
Cf. https://github.com/UnixJunkie/hoogle_for_ocaml
So, the short answer is:
Map.cadinal your_map
PS: and yes, the OCaml community is still dearly missing the equivalent of Hoogle in the Haskell community. There are some hacks around, like the one I just linked, but we would need a serious one, correctly working, actively maintained and largely vetted by the community
I would like to know how to take a list of tuples as a parameter or if there is an easier solution.
I am new to Haskell (only started a week ago) and I made this function to check if the tuple acts as a Pythagorean Triple.
pyTheorem (a,b,c) = a ^ 2 + b ^ 2 == c ^ 2
let x = pyTheorem (3,4,5)
So how would I define a function where it takes a list of tuples and returns the tuples that are Pythagorean Triples? Also, if there is a better way of doing this, please elaborate.
I looked up some similar questions but I couldn't find something that seemed to fit this example.
Side Note: I find that some of the examples in LYAH I can't seem to use in the online terminal: https://ghc.io/
So I am using http://www.tutorialspoint.com/compile_haskell_online.php instead. Are there any big differences I should be aware of?
Thanks.
I think is all you need
filterPy : [(Int,Int,Int)] -> [(Int,Int,Int)]
filterPy ls = filter pyTheorem ls
Real afficionados would also write it 'point free'
filterPy = filter pyTheorem
I'm currently working with vellvm, developing a transformation on it. I'm a coq newbie.
This is the atom implementation:
http://www.cis.upenn.edu/~plclub/popl08-tutorial/code/coqdoc/Atom.html
In vellvm, atoms are used as ids and labels, for example.
I would like to insert a block of code in one llvm transformation, and for that I would have to give a label of type "atom". How can I construct a Atom label?
Putting my question a bit more general:
1) Why someone would want to use Atom?
2) How can I construct one?
3) If I construct this way, will I have trouble taking in consideration that the atoms might be used differently in the code?
Thanks!
Edit: Code for id and labels
Definition id := atom. (*r identities *)
Definition l := atom. (*r labels *)
Looking at the file you pointed (by Chargueraud and Aydemir), you understand that the atom type is used to represent any type that you could use to give names to things.
The function atom_fresh_for_list should be used to create a new atom. The type of this function indicates that it returns not only an arbitrary atom, but also some proof that the atom you get is not present in the list you gave as argument. This is how you create a new one: you put all the old ones in a list, and you call the function atom_fresh_for_list with it as argument. As a result you obtain a value of type {x : atom | ...}. This is not exactly an atom: it is an atom with more information. You can get hold of the atom by writing:
let (v, h) := atom_fresh_for_list ... in ...
and then, in the second "...", the variable v contains the atom and you can use it. If you need to prove that this atom is a new one, then you can use the other variable h for that.
Yves
Yves was able to answer it partially, just don't have an example of how to construct a atom. You need to use projT1. Following are the code for this:
Definition an_atom : atom := (projT1 (atom_fresh_for_list nil)).
Where nil is any list.
I'm ocaml absolute beginner and I'm writing some code for classes and I've got a problem with such a line:
datatype logicexpr = Var of string
| Neg of logicexpr
| And of logicexpr * logicexpr
| Or of logicexpr * logicexpr;
let rec distributeLeft(X, And(e,f)) = And(distributeLeft(X, e),distributeLeft(Y, f))
| Or(X, Y);;
Why I get a syntax error here?
The function distributeLeft defined by:
fun distributeLeft(X, And(e,f)) = And(distributeLeft(X,e),distributeLeft(X,f))
| distributeLeft(X, Y) = Or(X, Y);
Can be translated in OCaml to something like:
let rec distibuteLeft = function
| (X, And(e,f)) -> And(distributeLeft(X,e),distributeLeft(X,f))
| (X, Y) -> Or(X, Y)
And so on ...
There is no way to really tell what you are trying to achieve, since the similarities to OCaml syntax in your code are only remote. I think you got that code you are presenting from somewhere, so maybe it would help to find out what the original language was, since it is clearly not OCaml.
Although I have no idea, what exactely you are trying to do, I can still try to give some general hints.
First: Do not use parentheses around arguments in OCaml. They are not needed and not customarily used.
let rec fac n = if n < 0 then 1 else n * (fac (n-1))
is a very common definition of the factorial function. As you can see the parameter n is used without any parentheses.
Second: It seems like you are trying to do some pattern matching. Although I do not know the language you are using it seems like this, because the code style is similar to a patter matching in haskell.
Pattern matching in OCaml needs to be done explicitly by using the match ... with clause. Here is an example using the data you defined:
type logicexpr = Var of string
| Neg of logicexpr
| And of logicexpr * logicexpr
| Or of logicexpr * logicexpr
let rec distributeLeft x y =
match y with
And(e,f) -> And(distributeLeft(X,e),distributeLeft(X,f))
| Or(e,f) -> Or(distributeLeft(X,e),distributeLeft(Y,f))
(* ... *)
This is just an example for the correct syntax, so do not use it. You need to really understand the program you have taken from somewhere to be able to translate it to another language. Also be very carefull, if you take for example a Haskell program a lot of algorithms will fail, because they often require special language feature, which cannot be easily translated.
So first figure out, how this program works, then get to know the syntax, and then attempt a translation. If you get stuck somewhere while doing this, just come back and maybe someone will be able to help you better.
It's hard to give help with so little context (as pad is pointing out). However, the symbol "|" isn't an operator in OCaml. It's part of the pattern syntax. Since we don't know what you're trying to do it's hard to say more. Maybe you wanted to use "||" which is a boolean operator. Or maybe you're trying to do something with a pattern that's not possible.