julia lang - how to apply multiple functions to a value - function

I would like to apply a set of functions to a value and get a set of values as output. I see in help?> groupby (DataFrames package) we can do:
> df |> groupby(:a) |> [sum, length]
> df |> groupby([:a, :b]) |> [sum, length]
but can we do
> [sum, length](groupby([:a, :b]))
MethodError: objects of type Array{Function,1} are not callable
square brackets [] for indexing an Array.
eval_user_input(::Any, ::Base.REPL.REPLBackend) at ./REPL.jl:64
in macro expansion at ./REPL.jl:95 [inlined]
in (::Base.REPL.##3#4{Base.REPL.REPLBackend})() at ./event.jl:68
or even
> [sum, length](1:5)
I would expect the output:
[15, 5]

Yes and no. (i.e. yes it's possible, but no, not with that syntax):
No: The syntax you see with |> and dataframes is not general syntax. It's just how the |> method is defined for dataframes. See its definition in file grouping.jl (line 377) and you'll see it's just a wrapper to another function, and it's defined to either accept a function, or a vector of functions.
PS: Note that the generic |> which "pipes" an argument into a function, only expects 1-argument functions on the right hand side, and has very little to do with this particular "dataframe-overloaded" method.
Yes:
You can apply a set of functions to a set of inputs in other ways.
One simple way, e.g. would be via a list comprehension:
julia> a = [1 2 3;2 3 4];
julia> [f(a) for f in [sum, length, size]]
3-element Array{Any,1}:
15
6
(2,3)
Or using map:
julia> map( (x) -> x(a), [sum, length, size])
etc.
PS: If you're keen to use |> to achieve this, clearly you could also do something like this:
julia> a |> (x) -> [sum(x), length(x), size(x)]
but presumably that defeats the purpose of what you're trying to do :)

Your proposed syntax is possible in Julia by adding a method to the type Array{T} (here, T is restricted to subtypes of Function):
julia> (a::Array{T}){T<:Function}(x) = [f(x) for f in a]
julia> [sin cos; exp sqrt](0)
2×2 Array{Float64,2}:
0.0 1.0
1.0 0.0
However, this has a large overhead if the number of functions is small. For maximum speed, one can use Tuples and a #generated function to unroll the loop manually:
julia> #generated (t::NTuple{N, Function}){N}(x) = :($((:(t[$i](x)) for i in 1:N)...),)
julia> (cos, sin)(0)
(1.0,0.0)

Related

error message by list comprehension with floored float numbers and in lambda functions

I'm learning Haskell and have some problems with list comprehension.
If I define a function to get a list of the divisors of a given number, I get an error.
check n = [x | x <- [1..(floor (n/2))], mod n x == 0]
I don't get why it's causing an error. If I want to generate a list from 1 to n/2 I can do it with [1..(floor (n/2))], but not if I do it in the list comprehension.
I tried another way but I get also an error (in this code I want to get all so called "perfect numbers")
f n = [1..(floor (n/2))]
main = print $ filter (\t -> foldr (+) 0 (f t) == t) [2..100]
Usually it is better to start writing a signature. While signatures are often not required, it makes it easier to debug a single function.
The signature of your check function is:
check :: (RealFrac a, Integral a) => a -> [a]
The type of input (and output) a thus needs to be both a RealFrac and an Integral. While technically speaking we can make such type, it does not make much sense.
The reason this happens is because of the use of mod :: Integral a => a -> a -> a this requires x and n to be both of the same type, and a should be a member of the Integral typeclass.
Another problem is the use of n/2, since (/) :: Fractional a => a -> a -> a requires that n and 2 have the same type as n / 2, and n should also be of a type that is a member of Fractional. To make matters even worse, we use floor :: (RealFrac a, Integral b) => a -> b which enforces that n (and thus x as well) have a type that is a member of the RealFrac typeclass.
We can prevent the Fractional and RealFrac type constaints by making use of div :: Integral a => a -> a -> a instead. Since mod already required n to have a type that is a member of the Integral typeclass, this thus will not restrict the types further:
check n = [x | x <- [1 .. div n 2], mod n x == 0]
This for example prints:
Prelude> print (check 5)
[1]
Prelude> print (check 17)
[1]
Prelude> print (check 18)
[1,2,3,6,9]

Julia: creating a method for Any vector with missing values

I would like to create a function that deals with missing values. However, when I tried to specify the missing type Array{Missing, 1}, it errors.
function f(x::Array{<:Number, 1})
# do something complicated
println("no missings.")
println(sum(x))
end
function f(x::Array{Missing, 1})
x = collect(skipmissing(x))
# do something complicated
println("removed missings.")
f(x)
end
f([2, 3, 5])
f([2, 3, 5, missing])
I understand that my type is not Missing but Array{Union{Missing, Int64},1}
When I specify this type, it works in the case above. However, I would like to work with all types (strings, floats etc., not only Int64).
I tried
function f(x::Array{Missing, 1})
...
end
But it errors again... Saying that
f (generic function with 1 method)
ERROR: LoadError: MethodError: no method matching f(::Array{Union{Missing, Int64},1})
Closest candidates are:
f(::Array{Any,1}) at ...
How can I say that I wand the type to be union missings with whatever?
EDIT (reformulation)
Let's have these 4 vectors and two functions dealing with strings and numbers.
x1 = [1, 2, 3]
x2 = [1, 2, 3, missing]
x3 = ["1", "2", "3"]
x4 = ["1", "2", "3", missing]
function f(x::Array{<:Number,1})
println(sum(x))
end
function f(x::Array{String,1})
println(join(x))
end
f(x) doesn't work for x2 and x3, because they are of type Array{Union{Missing, Int64},1} and Array{Union{Missing, String},1}, respectively.
It is possible to have only one function that detects whether the vector contains missings, removes them and then deals appropriately with it.
for instance:
function f(x::Array{Any, 1})
x = collect(skipmissing(x))
print("removed missings")
f(x)
end
But this doesn't work because Any indicates a mixed type (e.g., strings and nums) and does not mean string OR numbers or whatever.
EDIT 2 Partial fix
This works:
function f(x::Array)
x = collect(skipmissing(x))
print("removed missings")
f(x)
end
[But how, then, to specify the shape (number of dimensions) of the array...? (this might be an unrelated topic though)]
You can do it in the following way:
function f(x::Vector{<:Number})
# do something complicated
println("no missings.")
println(sum(x))
end
function f(x::Vector{Union{Missing,T}}) where {T<:Number}
x = collect(skipmissing(x))
# do something complicated
println("removed missings.")
f(x)
end
and now it works:
julia> f([2, 3, 5])
no missings.
10
julia> f([2, 3, 5, missing])
removed missings.
no missings.
10
EDIT:
I will try to answer the questions raised (if I miss something please add a comment).
First Vector{Union{Missing, <:Number}} is the same as Vector{Union{Missing, Number}} because of the scoping rules as tibL indicated as Vector{Union{Missing, <:Number}} translates to Array{Union{Missing, T} where T<:Number,1} and where clause is inside Array.
Second (here I am not sure if this is what you want). I understand you want the following behavior:
julia> g(x::Array{>:Missing,1}) = "$(eltype(x)) allows missing"
g (generic function with 2 methods)
julia> g(x::Array{T,1}) where T = "$(eltype(x)) does not allow missing"
g (generic function with 2 methods)
julia> g([1,2,3])
"Int64 does not allow missing"
julia> g([1,2,missing])
"Union{Missing, Int64} allows missing"
julia> g(["a",'a'])
"Any allows missing"
julia> g(Union{String,Char}["a",'a'])
"Union{Char, String} does not allow missing"
Note the last two line - although ["a", 'a'] does not contain missing the array has Any element type so it might contain missing. The last case excludes it.
Also you can see that you could change the second parameter of Array{T,N} to something else to get a different dimensionality.
Also this example works because the first method, as more specific, catches all cases that allow Missing and a second method, as more general, catches what is left (i.e. essentially what does not allow Missing).

Wrong arity of simple function in clojure

I've started to learn clojure. In my book there is following exercise:
Write a function, mapset, that works like map except the return value is a set:
(mapset inc [1 1 2 2])
; => #{2 3}
I've started with something like this:
(defn mapset
[vect]
(set vect))
The result is error
"Wrong number of args (2) passed to: core/mapset"
I tried [& args] as well.
So, the question is: how can I solve such problem?
Take a closer look at your call to mapset:
(mapset inc [1 1 2 2])
Since code is data, this "call" is just a list of three elements:
The symbol mapset
The symbol inc
The vector [1 1 2 2]
When you evaluate this code, Clojure will see that it is a list and proceed to evaluate each of the items in that list (once it determines that it isn't a special form or macro), so it will then have a new list of three elements:
The function to which the symbol core/mapset was bound
The function to which the symbol clojure.core/inc was bound
The vector [1 1 2 2]
Finally, Clojure will call the first element of the list with the rest of the elements as arguments. In this case, there are two arguments in the rest of the list, but in your function definition, you only accounted for one:
(defn mapset
[vect]
(set vect))
To remedy this, you could implement mapset as follows:
(defn mapset
[f vect]
(set (map f vect)))
Now, when you call (mapset inc [1 1 2 2]), the argument f will be found to the function clojure.core/inc, and the argument vect will be bound to the vector [1 1 2 2].
Your definition of mapset takes a single argument vect
At a minimum you need to take 2 arguments, a function and a sequence
(defn mapset [f xs] (set (map f xs)))`
But it is interesting to think about this as the composition of 2 functions also:
(def mapset (comp set map))

How to pass the return type of a function to an exception in OCaml?

I have function 'my_a' in OCaml, which could have a very complicated return type:
exception Backtrack
exception Continue of (* How do I put the type of function 'my_a' here? *)
let my_a arg = try do_stuff (List.hd arg)
with
| Backtrack -> my_a (List.tl arg)
| Continue (found_answer) -> (try my_a (List.tl arg)
with
| Backtrack -> raise Continue(found_answer)
| Continue (other_answer) ->
raise Continue (compare_answer(found_answer,other_answer));;
(* the caller of my_a will handle the Continue exception to catch the found value
if something was found*)
This is my problem: I'm using backtrack to find a solution. When a backtrack exception is raised by do_stuff, there was no solution going that path. However, when it raises an exception of type Continue, it means it found a solution, but, it may not be the best solution there is, that's when I try again with a different path. If there is another exception, I want to return the answer it already had found.
The thing is, to be able to use that feature of OCaml I need to to tell it what data type Continue will be carrying. What the OCaml top level returns when i define my_a:
'a * ('a -> ('a, 'b) symbol list list) ->
'b list -> ('a * ('a, 'b) symbol list) list * 'b list = <fun>
Does anyone have any idea of how to do that, or a different solution to that?
It's hard to tell exactly what you're asking. I think you might be asking how to get the type inside the Two exception to be set to the return type of A without having to specifically declare this type. I can't think of any way to do it.
Things might go better if you used option types instead of exceptions. Or you can just declare the return type of A explicitly. It might be good documentation.
A couple of side comments: (a) function names have to start with a lower case letter (b) this code looks quite convoluted and hard to follow. There might be a simpler way to structure your computation.
You are gaining nothing by using exceptions. Here is a possible solution.
(** There are many ways to implement backtracking in Ocaml. We show here one
possibility. We search for an optimal solution in a search space. The
search space is given by an [initial] state and a function [search] which
takes a state and returns either
- a solution [x] together with a number [a] describing how good [x] is
(larger [a] means better solution), or
- a list of states that need still to be searched.
An example of such a problem: given a number [n], express it as a sum
[n1 + n2 + ... + nk = n] such that the product [n1 * n2 * ... * nk] is
as large as possible. Additionally require that [n1 <= n2 <= ... <= nk].
The state of the search can be expressed as pair [(lst, s, m)] where
[lst] is the list of numbers in the sum, [s] is the sum of numbers in [lst],
and [m] is the next number we will try to add to the list. If [s = n] then
[lst] is a solution. Otherwise, if [s + m <= n] then we branch into two states:
- either we add [m] to the list, so the next state is [(m :: lst, m+s, m)], or
- we do not add [m] to the list, and the next state is [(lst, s, m+1)].
The return type of [search] is described by the following datatype:
*)
type ('a, 'b, 'c) backtrack =
| Solution of ('a * 'b)
| Branches of 'c list
(** The main function accepts an initial state and the search function. *)
let backtrack initial search =
(* Auxiliary function to compare two optional solutions, and return the better one. *)
let cmp x y =
match x, y with
| None, None -> None (* no solution *)
| None, Some _ -> y (* any solution is better than none *)
| Some _, None -> x (* any solution is better than none *)
| Some (_, a), Some (_, b) ->
if a < b then y else x
in
(* Auxiliary function which actually performs the search, note that it is tail-recursive.
The argument [best] is the best (optional) solution found so far, [branches] is the
list of branch points that still needs to be processed. *)
let rec backtrack best branches =
match branches with
| [] -> best (* no more branches, return the best solution found *)
| b :: bs ->
(match search b with
| Solution x ->
let best = cmp best (Some x) in
backtrack best bs
| Branches lst ->
backtrack best (lst # bs))
in
(* initiate the search with no solution in the initial state *)
match backtrack None [initial] with
| None -> None (* nothing was found *)
| Some (x, _) -> Some x (* the best solution found *)
(** Here is the above example encoded. *)
let sum n =
let search (lst, s, m) =
if s = n then
(* solution found, compute the product of [lst] *)
let p = List.fold_left ( * ) 1 lst in
Solution (lst, p)
else
if s + m <= n then
(* split into two states, one that adds [m] to the list and another
that increases [m] *)
Branches [(m::lst, m+s, m); (lst, s, m+1)]
else
(* [m] is too big, no way to proceed, return empty list of branches *)
Branches []
in
backtrack ([], 0, 1) search
;;
(** How to write 10 as a sum of numbers so that their product is as large as possible? *)
sum 10 ;; (* returns Some [3; 3; 2; 2] *)
OCaml happily informs us that the type of backtrack is
'a -> ('a -> ('b, 'c, 'a) backtrack) -> 'b option
This makes sense:
the first argument is the initial state, which has some type 'a
the second argument is the search function, which takes a state of type 'a and
returns either a Solution (x,a) where x has type 'b and a has type 'c,
or Branches lst where lst has type 'a list.

Sort a list into tuples

I’m new to Haskell and am trying to sort a list of tuples using their first element, using the sort function. So if I had ["a", "b", "a", "c", "c"] I would get something like [(1,"b"), (2,"a"), (2,"c")] (in alphabetical order in the event of the same number).
How would I go about doing this? I am totally lost at the moment… I am still trying to get into the ‘Haskell way of thinking’.
import Data.List (sort, group)
import Control.Arrow ((&&&))
answer :: Eq a => [a] -> [(Int, a)]
answer = sort . map (length &&& head) . group . sort
But as you're a beginner, it's perhaps a bit much to tell you about &&&, so I'll rewrite it like this:
import Data.List (sort, group)
answer :: Eq a => [a] -> [(Int, a)]
answer = sort . map f . group . sort
where f xs # (x:_) = (length xs, x)
You'll note I'm calling sort twice. This is intentional.
The final sort (the one on the left) sorts the output list of tuples, and it just so happens that it sorts in ascending order of the first element of the tuple, breaking ties by sorting on the second element of the tuple.
The initial sort (the one on the right) sorts the input list, because of what group does: it groups adjacent equal elements into a sublist. (Incidentally, these sublists are guaranteed never to be empty --- otherwise it wouldn't be safe to use head or ignore the empty list option in the pattern match.)
The map f then turns these lists (e.g. ["a", "a"]) into what we're interested in: the number of times these elements occur, and a single representative of these elements (e.g. (2, "a")).
The idiom here is that we're using a pipeline: our input goes into a function, the output of that function goes into another function, and so on until the function at the end of the pipeline produces output that we present as our own output. Note that this only works because each function takes only a single argument (map takes two arguments, f is the first of those arguments, so map f takes one argument).
As a consequence of this, answer is a function even though its argument doesn't explicitly appear. This is point-free style.
In non point-free style, it would look like
answer xs = sort . map f . group . sort $ xs
where f xs # (x:_) = (length xs, x)
or
answer xs = sort $ map f $ group $ sort xs
where f xs # (x:_) = (length xs, x)
or
answer xs = sort (map f (group (sort xs)))
where f xs # (x:_) = (length xs, x)
It is a good idea to use point-free style when it makes your code clearer.
If you like, you can use the <<< operator (from Control.Arrow again, sorry) to make the dataflow direction superficially more explicit:
import Data.List (sort, group)
import Control.Arrow ((<<<))
answer :: Eq a => [a] -> [(Int, a)]
answer = sort <<< map f <<< group <<< sort
where f xs # (x:_) = (length xs, x)
Some people think that this is the wrong way round and want the functions that "happen" first to be on the left. These people can use >>> (also from Control.Arrow), which is exactly the same as <<< except its arguments are flipped round:
import Data.List (sort, group)
import Control.Arrow ((>>>))
answer :: Eq a => [a] -> [(Int, a)]
answer = sort >>> group >>> map f >>> sort
where f xs # (x:_) = (length xs, x)