I am completely new to OCaml, so I am having some trouble with the basics. For my program, I have to match a nucleotide with it's complement (G -> C, C -> G, A -> T, T -> A) in order to find the other half of the double helix. The general idea is that DNA is composed of 2 complementary helixes, each of which is a sequence of nucleotides. Currently, I am trying to compute the other half of the double helix.
So far, I have represented the nucleotides with an enumeration and I've represented the DNA with a nucleotide list which corresponds to one helix.
type nucleotide =
| G
| C
| A
| T
type helix = nucleotide list
let rec complementary_helix (x:helix): helix =
| [G] -> [C]
| [C] -> [G]
| [A] -> [T]
| [T] -> [A]
end
I know something is missing here, but I don't know how to go about it. Can somebody steer me in the right direction?
You're basically just missing List.map:
let complement = function
| G -> C
| C -> G
| A -> T
| T -> A
let complementary_helix (x: helix) : helix =
List.map complement x
(For what it's worth, it's not necessary to specify types. OCaml will infer the types. It's good style to specify them for documentation but maybe not if they're obvious.)
Edit
OK, I guess this is a homework problem in which you're supposed to use recursion to solve the problem.
The way to think of recursion is that you want to solve a little piece of the problem, which gives you a smaller problem to solve. You pass the smaller problem to yourself (either before or after you solve your little piece). You also need to know when the problem has gotten so small there's no more work to do on it.
In your case, the little piece would be to translate one nucleotide to its complement. You're doing that semi-OK (you have lists where you would really just want to work on single nucleotides). But you're not passing the remainder of the problem to yourself to solve recursively. You're also not checking whether the problem is so small there's nothing to do.
For functions on lists, around 99% of the time you're going to make the problem smaller by splitting the list into the head (a single element) and the tail (a list that's smaller by one). That will work for you here.
Edit 2
As an example of how list recursion looks, here's a function that adds up all the integers in a list:
let rec sum l =
match l with
| [] -> 0
| head :: tail -> head + sum tail
This has all the parts I described. The match is used both to tell when the problem is trivial (when the list is empty) and to split the list into the head and the tail. Assuming you had the sum for the tail (which you can get recursively), the answer is pretty obvious. You just need to add the head onto this sum. You just need to ask yourself (almost always): if I had the answer for the tail of the list, what would I need to do to combine it with the head?
Related
I am currently working on a Morse code encoder in Haskell. This is my first time working in Haskell and I'm finding it difficult to think in a "functional" way. So far I have come up with this:
module Formative1
(encode, decode, toTree, toTable)
where
import safe Lib
encode :: String -> [MorseUnit]
encode str = codeText(words str)
codeWord :: String -> [MorseUnit]
codeWord word = map codeSymbol word
codeText :: [String] -> [MorseUnit]
codeText list = map codeWord list
To explain my code:
encode is the main function. It uses words to break down sentences into a list of words. codeText is used to apply the function codeWord over each word in the list. codeWord then maps over each character in each word and finds the MorseUnit using codeSymbol.
I have two issues with this solution:
Issue 1: I get an error every time I run it due to [MorseUnit] not matching [[MorseUnit]], I believe this is due to me using map twice so it's made a list within a list. But I can't think of another solution without using map.
Issue2: The rules of Morse Code state, after each letter, there should be a "shortGap", and after each word, there should be a "mediumGap". I have no idea how to insert either string inbetween each element of the list (I would insert shortGap between every element in map codeSymbol word so the shortGaps are between each letter, and I would insert mediumGap between every element in map codeWord list so the mediumGaps are between each word). I also don't understand at what point would I add the gaps because I don't want to accidentally apply codeSymbol to any of the gaps and replace them.
Any solutions would be helpful! Thank you.
Issue 1
You are exactly correct that the error is due to two maps. But you can also see it from the type signatures:
codeText list = map codeWord list (where list :: [String])
codeWord :: String -> [MorseUnit]
map :: (a -> b) -> [a] -> [b]
If you replace (a -> b) with (String -> [MorseUnit]), then [a] becomes [String], and [b] becomes [[MorseUnit]].
As in mathematics there are many ways to do it. Obviously you could just concat the resulting list. Notice the straightforward [[a]] -> [a] signature.
Notice that immediately after that there is concatMap. You could use it in place of map, and it would flatten the result for you.
To further confuse you, in case you find your parameter appearing last in both the declaration and the definition, you could omit it:
codeText = concatMap codeWord
I recommend you use Hoogle to search for the function signature you want.
Issue 2
First, since you need to distinguish between word and symbols, it seems to me you might not need to flatten the list so early. I am not familiar with Morse code so I don't fully understand what you want to do there. It would be much more clear if you could express your concept in types and signatures. My suggestion is to look at intersperse :: a -> [a] -> [a] or intercalate :: [a] -> [[a]] -> [a] to insert your gaps. They need to be imported with import Data.List.
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 have been trying to do a function that returns to me the first (or all it might work to but I do prefer just the first), element of a list of lists that is single, i mean:
[[x;y;z];[a;b;c];[a];[b]]
In this case I would like to get returned the a or [a] but I cant I tried to do a function something like:
let rec find_unit ll =
match ll with
| [x] -> [x]
and so on...
But every time I try something like this, I get in a recursion that never stops, or the function simple dont return the element. Can someone tell me how to do it properly? I still cant understand a lot of OCaml syntax... Just like in the example I dont know that to put in the line of |[x] -> [x], particularly the first [x].
Sorry for the question but I am destroying my code now and I cant find a solution.
Try decomposing your problem into smaller subproblems.
(1) Your problem overall looks like an instance of the more general 'find'-problem, which has already been solved. See the standard function List.find or (if you want to find them all... List.find_all. Both functions need a predicate to pick the right element(s) from the list.
(2) You need a way to determine if some list is a singleton. It's easy, use pattern-mathing.
let is_singleton xs = function
| [_] -> true
| _ -> false
(3) Now, combine the above and you'll get a solution.
A couple of observations on the code you give:
Your pattern needs to match the whole string ll, but the pattern you give seems to be intended to match just one element of ll. A pattern more like [x] :: rest is going to work better.
The way to avoid infinite recursion is always the same. First, make sure you check for the smallest possible input (the basis). For your problem this will be the case when ll is an empty list. Second, if you haven't found what you're looking for, continue the search on a smaller problem. In your case this will mean searching the tail of your list.
You also need to decide what to do when there is no element of the list like the one you're looking for. If you return [x] when you find it, you could return [] (say) if you don't find it. Or you could raise an exception like Not_found.
(As a side comment, lists and arrays are different things in OCaml. I removed the array tag, as your question seems to be about lists.)
Well all answers here helped me find a way to get the solution, and I am going to put it here because it might help someone else.
I used the function:
let is_single xs = function
| [_] -> true
| _ -> false
to do: let teste xs = List.filter(fun inner ->(is_single inner)inner)xs;; This teste function is returning to me a List of Lists with all single elements, so to get only one element inside of that lists i did: List.hd(List.hd teste xs)
I have this function that takes one lists and checkes for duplicates, if any duplicates are found they are added to a new list like this:
let foo1 z list = list |> List.filter (fun e -> e <= z)
this gives foo1 1 [2;3;4;1;5;1;6;1] => [1;1;1]
the problem is that I don't want to use any of the builtin functions in f#
You asked a number of basic F# questions on list processing already, so I recommend reading some introductions first and trying it yourself.
Working with Functional Lists explains how F# lists work
Introduction to F# has a tutorial on lists and pattern matching with recursion
Using built-in functions is the right way to solve the problem in practice. If you want to learn F# and understand recursion, then read the above first. Then you should be able to write something like:
let rec duplicates z = function
// If the list is empty, return empty list of duplicates
| [] -> []
// If it starts with 'z' then return one duplicate and recursively process the rest
| x::xs when x = z -> x::(duplicates x xs)
// If it starts with something else, then skip the first element and process the rest
| x::xs -> duplicates z xs
There are many F# introductions that explain how filter and similar functions are implemented. The F# wikibook covers this topic and you'll find it in most of the F# books (see a list on fsharp.org) and Working lists section on www.tryfsharp.org covers this too.
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.