Related
I want to create a list of variations of applying a function to every element of a list. Here is a quick example of what I mean.
applyVar f [a, b, c]
>> [[(f a), b, c], [a, (f b), c], [a, b, (f c)]]
Essentially It applies a function to each element of a list individually and stores each possible application in an array.
I'm not too sure how to approach a problem like this without using indexes as I have heard they are not very efficient. This is assuming that the function f returns the same type as the input list.
Is there a pre-existing function to get this behavior? If not what would that function be?
To see if there's a pre-existing function, first figure out its type. In this case, it's (a -> a) -> [a] -> [[a]]. Searching for that type on Hoogle only returns a handful of matches, and by inspection, none of them do what you want.
To write it yourself, note that it operates on a list, and the best way to figure out how to write a function on a list is to define it inductively. This means you need to build two cases: one for an empty list, and one for a non-empty list that assumes you already know the answer for its tail:
applyVar f [] = _
applyVar f (x:xs) = _ -- use `applyVar f xs` somehow
Now we just need to fill in the two blanks. For the nil case, it's easy. For the cons case, note that the first sublist starts with f a, and the rest will all start with a. Then, note that the tails of the rest look an awful lot like the answer for the tail. From there, the pattern should become clear.
applyVar f [] = []
applyVar f (x:xs) = (f x:xs):map (x:) (applyVar f xs)
And here's a quick demo/test of it:
Prelude> applyVar (+10) [1,2,3]
[[11,2,3],[1,12,3],[1,2,13]]
Note that, as is often the case, lens contains some tools that provide this as a special case of some far more abstract tooling.
$ cabal repl -b lens,adjunctions
Resolving dependencies...
GHCi, version 8.10.3: https://www.haskell.org/ghc/ :? for help
> import Control.Lens
> import Control.Comonad.Representable.Store
> let updateEach f = map (peeks f) . holesOf traverse
> :t updateEach
updateEach :: Traversable t => (s -> s) -> t s -> [t s]
> updateEach negate [1..3]
[[-1,2,3],[1,-2,3],[1,2,-3]]
> import qualified Data.Map as M
> updateEach (*3) (M.fromList [('a', 1), ('b', 2), ('c', 4)])
[fromList [('a',3),('b',2),('c',4)],fromList [('a',1),('b',6),('c',4)],fromList [('a',1),('b',2),('c',12)]]
This is honestly way overkill, unless you start needing some of the ways lens gets more compositional, like so:
> let updateEachOf l f = map (peeks f) . holesOf l
> updateEachOf (traverse . filtered even) negate [1..5]
[[1,-2,3,4,5],[1,2,3,-4,5]]
> updateEachOf (traverse . ix 2) negate [[1,2],[3,4,5],[6,7,8,9],[10]]
[[[1,2],[3,4,-5],[6,7,8,9],[10]],[[1,2],[3,4,5],[6,7,-8,9],[10]]]
But whether you ever end up needing it or not, it's cool to know that the tools exist.
Yes. Two functions, inits and tails:
foo :: (a -> a) -> [a] -> [[a]]
foo f xs = [ a ++ [f x] ++ b | a <- inits xs
| (x:b) <- tails xs]
(with ParallelListComp extension; equivalent to using zip over two applications of the two functions, to the same input argument, xs, in the regular list comprehension).
Trying it out:
> foo (100+) [1..5]
[[101,2,3,4,5],[1,102,3,4,5],[1,2,103,4,5],[1,2,3,104,5],[1,2,3,4,105]]
I am writing a simple OCaml function that creates an association list. The input is a string which is converted to a list of non-unique words in same order as in string, then the output is an association list of (word, [indices in list]).
Example
let f "a b c b a b" = ...
expected output => [("a", [0,4]), ("b", [1,3,5]), ("c", [2])] # order not important
So far I have managed to get to this intermediate output
[("b", 5); ("a", 4); ("b", 3); ("c", 2); ("b", 1); ("a", 0)]
but I am stuck trying to figure out how to reduce this to the final result.
Would it make more sense to create a Hashtbl from the original input? Then Hashtbl -> list??
Or is it a simple matter to reduce the intermediate result? The environment I am working in does not have access to List.reduce, so I would have to write a reduce function manually.
As I look at this it seems a Hashtbl would be more efficient as the number of words grows.
EDIT: Hashtbl definitely seems like the way to go. I already have the following hashtable:
"a" : [4,0], "b" : [5,3,1], "c" : [2]
But I can not figure out how to convert to a list now. Hashtbl.iter operates on every individual binding so, for example, it iterates over ("a", 4) and ("a", 0) separately (my understanding) which defeats the purpose. Suggestions?
I don't understand your description of the hashtable. Is the type of the hashtable (string, int) Hashtbl.t or is it (string, int list) Hashtbl.t? If it's the latter, you can just use Hashtbl.iter or (possibly better) Hashtbl.fold.
If your hashtable is of type (string, int) Hashtbl.t you could perhaps rewrite your code to keep a list of ints instead of an individual int. Then it will be of type (string, int list) Hashtbl.t.
Update
If your hashtable is of type (string, int list) Hashtbl.t then you can just use iter or fold if you make sure you have only one entry for each key.
The document is describing the following phenomenon:
# let h = Hashtbl.create 10;;
val h : ('_a, '_b) Hashtbl.t = <abstr>
# Hashtbl.add h "a" 3;;
- : unit = ()
# Hashtbl.add h "a" 4;;
- : unit = ()
# h;;
- : (string, int) Hashtbl.t = <abstr>
# Hashtbl.iter (fun s i -> Printf.printf "%s %d\n" s i) h;;
a 4
a 3
- : unit = ()
#
If you use Hashtbl.add to add new entries to a hashtable without removing the old ones, the entries accumulate.
If you use Hashtbl.replace rather than Hashtbl.add, things will work more reasonably.
# let h = Hashtbl.create 10;;
val h : ('_a, '_b) Hashtbl.t = <abstr>
# Hashtbl.replace h "a" 3;;
- : unit = ()
# Hashtbl.replace h "a" 4;;
- : unit = ()
# h;;
- : (string, int) Hashtbl.t = <abstr>
# Hashtbl.iter (fun s i -> Printf.printf "%s %d\n" s i) h;;
a 4
- : unit = ()
If you have a hashtable of the right type and use Hashtbl.replace to update your entries you will be OK.
Here is a working example using the Core library and associative lists.
open Core.Std
let compute str =
let letters = String.split str ~on:' ' in
let i = ref (-1) in
List.fold letters ~init:[] ~f:(fun acc letter ->
incr i;
match List.Assoc.find acc letter with
| Some l -> List.Assoc.add acc letter (List.append l [!i])
| None -> List.Assoc.add acc letter [!i]
)
Here is an example:
compute "a b c b a b";;
- : (string, int list) List.Assoc.t =
[("b", [1; 3; 5]); ("a", [0; 4]); ("c", [2])]
The trick here is to use List.fold to iterate over the split string and update the associative list.
Create Hashtbl
let my_hash = Hashtbl.create 12;;
let l=[("b", 5); ("a", 4); ("b", 3); ("c", 2); ("b", 1); ("a", 0)] ;;
List.iter (fun (k,v) ->
Hashtbl.add my_hash k v
) l;;
Program
let (opt_k',kacc,l)=
Hashtbl.fold ( fun k v (opt_k',kacc,l) ->
match opt_k' with
| None -> (Some k,v::kacc,l)
| Some k' -> if k=k' then (opt_k',v::kacc,l) else (Some k,v::[],(k',kacc)::l)
) my_hash (None,[],[])
in
match opt_k' with
| Some k' -> List.rev ((k',kacc)::l)
| _ -> List.rev l
;;
- : (string * int list) list = [("a", [4; 0]); ("b", [5; 3; 1]); ("c", [2])]
The standard library function List.fold_left covers the functionality that reduce provides in Lisp languages as well as in Core. You can use either hash tables or maps to build the result incrementally. While you can also use basic association lists from the List module, you risk worst case O(n^2) performance.
Thus:
module StringMap = Map.Make(String)
(* Extract words from a string. *)
let words = Str.split (Str.regexp "[ \t]+")
(* Build a string to int list dictionary from a string of words. *)
let dict ws =
let open StringMap in
let dict' =
(* Go through each word in turn; 'i' is a counter that is being
* incremented, 'mapping' accumulates the results. *)
List.fold_left (fun (mapping, i) word ->
try
let positions = find word mapping in
(* Add to existing entry *)
(add word (i :: positions) mapping, i+1)
with
(* New entry *)
Not_found -> (add word [i] mapping, i+1))
(empty, 0) in
let (mapping, _) = dict' (words ws) in
(* Entries are in reverse order, sort them out, then return as list. *)
(* The bindings themselves are already sorted. *)
bindings (map List.rev mapping)
let example = dict "a b c b a b"
This provides keys and positions in sorted order. The last line of dict can be simplified to bindings mapping if order does not matter.
Note that this requires the Str module to parse the string into a list of words and thus str.cma (for byte code compilation) or str.cmxa (for native code compilation) needs to be passed to the compiler, e.g.: ocamlc str.cma dict.ml. If you're using ocamlbuild, build with -package str.
I'm having a problem with understanding how F# works. I come from C# and I think that I'm trying to make F# work like C#. My biggest problem is returning values in the correct format.
Example:
Let's say I have function that takes a list of integers and an integer.
Function should print a list of indexes where values from list match passed integer.
My code:
let indeks myList n = myList |> List.mapi (fun i x -> if x=n then i else 0);;
indeks [0..4] 3;;
However it returns:
val it : int list = [0; 0; 0; 3; 0]
instead of just [3] as I cannot ommit else in that statement.
Also I have targeted signature of -> int list -> int -> int list and I get something else.
Same goes for problem no. 2 where I want to provide an integer and print every number from 0 to this integer n times (where n is the iterated value):
example:
MultiplyValues 3;;
output: [1;2;2;3;3;3]
Best I could do was to create list of lists.
What am I missing when returning elements?
How do I add nothing to the return
example: if x=n then n else AddNothingToTheReturn
Use List.choose:
let indeks lst n =
lst
|> List.mapi (fun i s -> if s = n then Some i else None)
|> List.choose id
Sorry, I didn't notice that you had a second problem too. For that you can use List.collect:
let f (n : int) : list<int> =
[1 .. n]
|> List.collect (fun s -> List.init s (fun t -> s))
printfn "%A" (f 3) // [1; 2; 2; 3; 3; 3]
Please read the documentation for List.collect for more information.
EDIT
Following s952163's lead, here is another version of the first solution without the Option type:
let indeks (lst : list<int>) (n : int) : list<int> =
lst
|> List.fold (fun (s, t) u -> s + 1, (if u = n then (s :: t) else t)) (0, [])
|> (snd >> List.rev)
This one traverses the original list once, and the (potentially much shorter) newly formed list once.
The previous answer is quite idiomatic. Here's one solution that avoids the use of Option types and id:
let indeks2 lst n =
lst
|> List.mapi (fun i x -> (i,x))
|> List.filter (fun x -> (fst x) % n = 0 )
|> List.map snd
You can modify the filter function to match your needs.
If you plan to generate lots of sequences it might be a good idea to explore Sequence (list) comprehensions:
[for i in 1..10 do
yield! List.replicate i i]
If statements are an expression in F# and they return a value. In this case both the IF and ELSE branch must return the same type of value. Using Some/None (Option type) gets around this. There are some cases where you can get away with just using If.
I'm trying to write a function that given a list of numbers, returns a list where every 2nd number is doubled in value, starting from the last element. So if the list elements are 1..n, n-th is going to be left as-is, (n-1)-th is going to be doubled in value, (n-2)-th is going to be left as-is, etc.
So here's how I solved it:
MyFunc :: [Integer] -> [Integer]
MyFunc xs = reverse (MyFuncHelper (reverse xs))
MyFuncHelper :: [Integer] -> [Integer]
MyFuncHelper [] = []
MyFuncHelper (x:[]) = [x]
MyFuncHelper (x:y:zs) = [x,y*2] ++ MyFuncHelper zs
And it works:
MyFunc [1,1,1,1] = [2,1,2,1]
MyFunc [1,1,1] = [1,2,1]
However, I can't help but think there has to be a simpler solution than reversing the list, processing it and then reversing it again. Could I simply iterate the list backwards? If yes, how?
The under reversed f xs idiom from the lens library will apply f to xs in reverse order:
under reversed (take 5) [1..100] => [96,97,98,99,100]
When you need to process the list from the end, usually foldr works pretty well. Here is a solution for you without reversing the whole list twice:
doubleOdd :: Num a => [a] -> [a]
doubleOdd = fst . foldr multiplyCond ([], False)
where multiplyCond x (rest, flag) = ((if flag then (x * 2) else x) : rest, not flag)
The multiplyCond function takes a tuple with a flag and the accumulator list. The flag constantly toggles on and off to track whether we should multiply the element or not. The accumulator list simply gathers the resulting numbers. This solution may be not so concise, but avoids extra work and doesn't use anything but prelude functions.
myFunc = reverse
. map (\(b,x) -> if b then x*2 else x)
. zip (cycle [False,True])
. reverse
But this isn't much better. Your implementation is sufficiently elegant.
The simplest way to iterate the list backwards is to reverse the list. I don't think you can really do much better than that; I suspect that if you have to traverse the whole list to find the end, and remember how to get back up, you might as well just reverse it. If this is a big deal, maybe you should be using some other data structure instead of lists—Vector or Seq might be good choices.
Another way to write your helper function is to use Traversable:
import Control.Monad.State
import Data.Traversable (Traversable, traverse)
toggle :: (Bool -> a -> b) -> a -> State Bool b
toggle f a =
do active <- get
put (not active)
return (f active a)
doubleEvens :: (Num a, Traversable t) => t a -> t a
doubleEvens xs = evalState (traverse (toggle step) xs) False
where step True x = 2*x
step False x = x
yourFunc :: Num a => [a] -> [a]
yourFunc = reverse . doubleEvens
Or if we go a bit crazy with Foldable and Traversable, we can try this:
Use Foldable's foldl to extract a reverse-order list from any of its instances. For some types this will be more efficient than reversing a list.
Then we can use traverse and State to map each element of the original structure to its counterpart in the reversed order.
Here's how to do it:
import Control.Monad.State
import Data.Foldable (Foldable)
import qualified Data.Foldable as F
import Data.Traversable (Traversable, traverse)
import Data.Map (Map)
import qualified Data.Map as Map
toReversedList :: Foldable t => t a -> [a]
toReversedList = F.foldl (flip (:)) []
reverse' :: Traversable t => t a -> t a
reverse' ta = evalState (traverse step ta) (toReversedList ta)
where step _ = do (h:t) <- get
put t
return h
yourFunc' :: (Traversable t, Num a) => t a -> t a
yourFunc' = reverse' . doubleEvens
-- >>> yourFunc' $ Map.fromList [(1, 1), (2, 1), (3, 1), (4, 1)]
-- fromList [(1,2),(2,1),(3,2),(4,1)]
-- >>> yourFunc' $ Map.fromList [(1, 1), (2, 1), (3, 1)]
-- fromList [(1,1),(2,2),(3,1)]
There's probably a better way to do this, though...
func xs = zipWith (*) xs $ reverse . (take $ length xs) $ cycle [1,2]
Is it really true that OCaml doesn't have a function which converts from a list to a set?
If that is the case, is it possible to make a generic function list_to_set? I've tried to make a polymorphic set without luck.
Fundamental problem: Lists can contain elements of any types. Sets (assuming you mean the Set module of the standard library), in contrary, rely on a element comparison operation to remain balanced trees. You cannot hope to convert a t list to a set if you don't have a comparison operation on t.
Practical problem: the Set module of the standard library is functorized: it takes as input a module representing your element type and its comparison operation, and produces as output a module representing the set. Making this work with the simple parametric polymoprhism of lists is a bit sport.
To do this, the easiest way is to wrap your set_of_list function in a functor, so that it is itself parametrized by a comparison function.
module SetOfList (E : Set.OrderedType) = struct
module S = Set.Make(E)
let set_of_list li =
List.fold_left (fun set elem -> S.add elem set) S.empty li
end
You can then use for example with the String module, which provides a suitable compare function.
module SoL = SetOfList(String);;
SoL.S.cardinal (SoL.set_of_list ["foo"; "bar"; "baz"]);; (* returns 3 *)
It is also possible to use different implementation of sets which are non-functorized, such as Batteries and Extlib 'PSet' implementation (documentation). The functorized design is advised because it has better typing guarantees -- you can't mix sets of the same element type using different comparison operations.
NB: of course, if you already have a given set module, instantiated form the Set.Make functor, you don't need all this; but you conversion function won't be polymorphic. For example assume I have the StringSet module defined in my code:
module StringSet = Set.Make(String)
Then I can write stringset_of_list easily, using StringSet.add and StringSet.empty:
let stringset_of_list li =
List.fold_left (fun set elem -> StringSet.add elem set) StringSet.empty li
In case you're not familiar with folds, here is a direct, non tail-recursive recursive version:
let rec stringset_of_list = function
| [] -> StringSet.empty
| hd::tl -> StringSet.add hd (stringset_of_list tl)
Ocaml 3.12 has extensions (7,13 Explicit naming of type variables and 7,14 First-class modules) that make it possible to instantiate and pass around modules for polymorphic values.
In this example, the make_set function returns a Set module for a given comparison function and the build_demo function constructs a set given a module and a list of values:
let make_set (type a) compare =
let module Ord = struct
type t = a
let compare = compare
end
in (module Set.Make (Ord) : Set.S with type elt = a)
let build_demo (type a) set_module xs =
let module S = (val set_module : Set.S with type elt = a) in
let set = List.fold_right S.add xs S.empty in
Printf.printf "%b\n" (S.cardinal set = List.length xs)
let demo (type a) xs = build_demo (make_set compare) xs
let _ = begin demo ['a', 'b', 'c']; demo [1, 2, 3]; end
This doesn't fully solve the problem, though, because the compiler doesn't allow the return value to have a type that depends on the module argument:
let list_to_set (type a) set_module xs =
let module S = (val set_module : Set.S with type elt = a) in
List.fold_right S.add xs S.empty
Error: This `let module' expression has type S.t
In this type, the locally bound module name S escapes its scope
A possible work-around is to return a collection of functions that operate on the hidden set value:
let list_to_add_mem_set (type a) set_module xs =
let module S = (val set_module : Set.S with type elt = a) in
let set = ref (List.fold_right S.add xs S.empty) in
let add x = set := S.add x !set in
let mem x = S.mem x !set in
(add, mem)
If you don't mind a very crude approach, you can use the polymorphic hash table interface. A hash table with an element type of unit is just a set.
# let set_of_list l =
let res = Hashtbl.create (List.length l)
in let () = List.iter (fun x -> Hashtbl.add res x ()) l
in res;;
val set_of_list : 'a list -> ('a, unit) Hashtbl.t = <fun>
# let a = set_of_list [3;5;7];;
val a : (int, unit) Hashtbl.t = <abstr>
# let b = set_of_list ["yes";"no"];;
val b : (string, unit) Hashtbl.t = <abstr>
# Hashtbl.mem a 5;;
- : bool = true
# Hashtbl.mem a 6;;
- : bool = false
# Hashtbl.mem b "no";;
- : bool = true
If you just need to test membership, this might be good enough. If you wanted other set operations (like union and intersection) this isn't a very nice solution. And it's definitely not very elegant from a typing standpoint.
Just extend the original type, as shown in
http://www.ffconsultancy.com/ocaml/benefits/modules.html
for the List module:
module StringSet = Set.Make (* define basic type *)
(struct
type t = string
let compare = Pervasives.compare
end)
module StringSet = struct (* extend type with more operations *)
include StringSet
let of_list l =
List.fold_left
(fun s e -> StringSet.add e s)
StringSet.empty l
end;;
Using the core library you could do something like:
let list_to_set l =
List.fold l ~init:(Set.empty ~comparator:Comparator.Poly.comparator)
~f:Set.add |> Set.to_list
So for example:
list_to_set [4;6;3;6;3;4;3;8;2]
-> [2; 3; 4; 6; 8]
Or:
list_to_set ["d";"g";"d";"a"]
-> ["a"; "d"; "g"]