So I'm writing a flatten fn, and I got it to this:
fun flatten ls = List.foldr op # [] ls
And I realized that naming the variable ls should be unnecessary, instead I could probably just paritally apply foldr. But this breaks:
val flatten = List.foldr op # []
Whats making it mess up? I seems like the typ would have to be inferred for both the fun declaration and for the partially applied foldr.
A similar sum function works, which makes me wonder why # is particularly not working:
val sum = List.foldr op + 0
Edit: the error I'm getting:
- val flatten = List.foldr op # [];
stdIn:1.6-2.13 Warning: type vars not generalized because of
value restriction are instantiated to dummy types (X1,X2,...)
val flatten = fn : ?.X1 list list -> ?.X1 list
- flatten [[1], [1]];
stdIn:3.1-3.19 Error: operator and operand don't agree [literal]
operator domain: ?.X1 list list
operand: int list list
in expression:
flatten ((1 :: nil) :: (1 :: nil) :: nil)
I'm a bit unclear on what error exactly you are referring to. You mention in the headline that you are getting an "operator domain error", however you code just produces a "value restriction" warning. There is a big difference.
Value restriction is one of the more complex things to get your head around, but in essence it is there to preserve type safety when having references in the language.
The MLton wiki has a great article on value restriction, which covers Why the value restriction exists, unnecessarily rejected programs, alternatives to the value restriction and how to work with the value restriction.
AJ,
Jesper's article both explains the warning you see, and is insightful, but for a more practical solution to your problem, you might want to try this:
val flatten = foldr op # ([]:int list);
I believe that should solve your problem.
EDIT: I chose int list as the explicit type because I observed the nature of your warning message, and inferred from there, int list was what you needed. [=
Note: Above solution destroys polymorphism and restricts input to the type chosen.
Related
I'm trying to figure out mutual recursion. I have this code:
fun take(L)=
if L=nil then nil
else hd(L) :: skip(tl(L))
AND
fun skip(L)=
if L=nil then nil
else take(tl(L));
but it gives me these errors:
stdIn:54.14-54.18 Error: unbound variable or constructor: skip
stdIn:55.1-55.4 Error: unbound variable or constructor: AND
What am I doing wrong?
Your immediate error is because Standard ML is case-sensitive, and all of its reserved words are in lowercase; so you need to write and rather than AND.
Additionally, fun introduces an entire declaration, not an individual binding, meaning that you need to remove the extra fun after and.
Lastly, your functions currently require the list to have an equality type (such as int list or string list), which may not be a deal-breaker, but given what the functions actually do, there's really no reason they can't support non-equality types such as real list. To achieve that, you should match the parameter against the pattern nil, instead of testing whether the parameter equals nil. (More generally, you should use pattern-matching in more places; you have no reason to call hd and tl.)
Putting it together:
fun take nil = nil
| take (h::t) = h :: skip t
and skip nil = nil
| skip (h::t) = take t
In F#, I find when I want to use takeWhile, I usually also want to use skipWhile, that is, take the list prefix that satisfies a predicate, and also remember the rest of the list for subsequent processing. I don't think there is a standard library function that does both, but I can write one easily enough.
My question is, what should this combination be called? It's obvious enough that there should be a standard name for it; what is it? Best I've thought of so far is split, which seems consistent with splitAt.
span is another name I've seen for this function. For example, in Haskell
This part of your question stood out to me (emphasis mine):
take the list prefix that satisfies a predicate, and also remember the rest of the list for subsequent processing
I am guessing that you want to recurse with the rest of the list and then apply this splitting function again. This is what I have wanted to do a few times before. Initially, I wrote the function that I think you are describing but after giving it more thought I realised that there might be a more general way to think about it and avoid the recursion completely, which usually makes code simpler. This is the function I came up with.
module List =
let groupAdjacentBy f xs =
let mutable prevKey, i = None, 0
xs
|> List.groupBy (fun x ->
let key = f x
if prevKey <> Some key then
i <- i + 1
prevKey <- Some key
(i, key))
|> List.map (fun ((_, k), v) -> (k, v))
let even x = x % 2 = 0
List.groupAdjacentBy even [1; 3; 2; 5; 4; 6]
// [(false, [1; 3]); (true, [2]); (false, [5]); (true, [4; 6])]
I found this one easier to name and more useful. Maybe it works for your current problem. If you don't need the group keys then you can get rid of them by adding |> List.map snd.
As much as I usually avoid mutation, using it here allowed me to use List.groupBy and avoid writing more code.
.slice could capture the intent of a contiguous range:
List.slice skipPredicate takePredicate
Could someone explain what the |> operator does? This code was taken from the reference here:
let m = PairsMap.(empty |> add (0,1) "hello" |> add (1,0) "world")
I can see what it does, but I wouldn't know how to apply the |> operator otherwise.
For that matter, I have no idea what the Module.() syntax is doing either. An explanation on that would be nice too.
Module.(e) is equivalent to let open Module in e. It is a shorthand syntax to introduce things in scope.
The operator |> is defined in module Pervasives as let (|>) x f = f x. (In fact, it is defined as an external primitive, easier to compile. This is unimportant here.) It is the reverse application function, that makes it easier to chain successive calls. Without it, you would need to write
let m = PairsMap.(add (1,0) "world" (add (0,1) "hello" empty))
that requires more parentheses.
The |> operator looks like the | in bash.
The basic idea is that
e |> f = f e
It is a way to write your applications in the order of execution.
As an exemple you could use it (I don't particularly think you should though) to avoid lets:
12 |> fun x -> e
instead of
let x = 12 in e
For the Module.() thing, it is to use a specific function of a given module.
You probably have seen List.map before.
You could of course use open List and then only refer to the function with map. But if you also open Array afterwards, map is now referring to Array.map so you need to use List.map.
The |> operator represents reverse function application. It sounds complicated but it just means you can put the function (and maybe a few extra parameters) after the value you want to apply it to. This lets you build up something that looks like a Unix pipeline:
# let ( |> ) x f = f x;;
val ( |> ) : 'a -> ('a -> 'b) -> 'b = <fun>
# 0.0 |> sin |> exp;;
- : float = 1.
The notation Module.(expr) is used to open the module temporarily for the one expression. In other words, you can use names from the module directly in the expression, without having to prefix the module name.
I'm teaching myself OCaml and I sometimes need to create a function where I'm not really sure what the proper solution should be. Here's one that I'm a little confused about.
I need a function that will prompt the user for individual float values and return everything entered in a float list. I can create this function but I'm not sure if its the proper/best way to do it in Ocaml.
Here's my attempt.
let rec get_floats() =
match
(
try Some(read_float())
with
| float_of_string -> None
)
with
| None -> []
| Some s -> s :: get_floats();;
This code works buts I'm at a loss deciding if its a 'proper OCaml' solution. Note, to exit the function and return the float list just enter a non-integer value.
(I hope that) this is a simple peephole rewrite involving no thought whatsoever of the function in your question:
let rec get_floats() =
try
let f = read_float() in (* as suggested by Martin Jambon *)
f :: (get_floats())
with
| float_of_string -> []
The idea I tried to apply here is that you do not need to convert the success/failure of read_float into an option that you immediately match: just do what you have to do with the value read, and let the with handle the failure case.
Now that I think of it, I should point out that in both your question and my rewrite, float_of_string is a fresh variable. If you meant to match a specific exception, you failed at it: all exception constructors, like datatype constructors, are Capitalized. You might as well have written with _ -> instead of with float_of_string ->, and a recent version of OCaml with all warnings active should tell you that your function (or mine) binds a variable float_of_string without ever using it.
Thanks everyone for the help. This works.
let rec get_floats() =
try
let x = read_float() in
x :: get_floats()
with
| _ -> [];;
List.iter (fun x -> print_endline(string_of_float x)) (get_floats());;
how can I easily take the following
[4]
and return the following:
4
I know that [4]!!0 works but doesn't seem to be a good strategy...
Just pattern match it:
getSingleton [a] = a
head is the normal answer, which you see three of (one with a custom name) - this is functionally the same as what you already know (x !! 0 ~ head x). I strongly suggest against partial functions unless you can prove (with local knowledge) that you'll never pass an empty list and result in a run-time exception.
If your function doesn't guarantee a non-empty list then use listToMaybe :: [a] -> Maybe a:
> listToMaybe [4]
Just 4
> listToMaybe [5,39,-2,6,1]
Just 5
> listToMaybe []
Nothing -- A 'Nothing' constructor instead of an exception
Once you have the Maybe a you can pattern match on that, keep it as Maybe and use fmap or a Maybe monad, or some other method to perform further operations.
Alternatively to gatoatigrado's solution you can also use the head function, which extracts the first element of a list, but will also work on lists with more than one element and additionally is a standard function in the Prelude. You just have to be careful not to apply it to empty lists or you will get a runtime exception.
Prelude> head [4]
4
Prelude> head []
*** Exception: Prelude.head: empty list
If you want this first item in a list you can just do
head [4]
[] is a monad. So you use the monad "extract" operation, <-
double x = 2*x
doubleAll xs = do x <- xs
return (double x)
Of course, the result of the monadic computation is returned in the monad. ;)