In F# / Excel-Dna, what is the idiomatic way to rewrite the following function for a vector of strings? (i.e. a function which sorts a "vector" (=1d Excel range) of strings).
[<ExcelFunction(Category="Some Cat", Description="Sort 1d range filled with doubles.")>]
let mySortDouble (vect : double[]) : double[] =
Array.sort vect
If I merely replace the double types with string types in the above snippet, I get this error message : Initialization [Error] Method not registered - unsupported signature, abstract or generic: 'MyFSFunctions.mySortString'
I saw this previous question where Govert suggests to use the "Registration extensions" but I have not found how to use it to answer my current question.
As you have mySortDouble written, it won't even compile, because it returns a double[], not a double.
Here's an example that works, with some minimal error handling added.
[<ExcelFunction(Category="Some Cat", Description="Sort 1D range of strings.")>]
let SortStrings (vect : obj[]) =
try
vect
|> Seq.cast<string>
|> Seq.sort
|> Seq.toArray
|> box
with
| ex -> box ExcelError.ExcelErrorNA
For Registration samples
ParameterConversionConfiguration()
.AddReturnConversion(fun (values: double[]) ->
Array.map (string >> box) values
)
Related
*I edited my original post to include more info.
I'm working on an F# assignment where I'm supposed to create a function that takes an "any list list" as input and outputs an "any list". It should be able to concatenate a list of lists into a single list.
Here's what my function looks like:
let llst = [ [1] ; [2;3] ; ['d';'e';'f'] ]
let concat (llst:'a list list) : 'a list =
List.concat llst
List.iter (fun elem -> printf "%d " elem) concat
This solution more or less copied directly from microsofts example of using the List.concat function, the only exception being the specification of input/output types.
When i run the code i get this error:
concat.fsx(7,43): error FS0001: This expression was expected to have type
''a list'
but here has type
''b list list -> 'b list'
So it appears that concat is turning my llst into a character list, which i don't understand.
Can anyone help me understand why I'm getting this type error and how I can write a function that takes the types that I need?
The problem is somewhere in your implementation of the concat function. It is hard to say where exactly without seeing your code, but since this is an assignment, it is actually perhaps better to explain what the error message is telling you, so that you can find the issue yourself.
The error message is telling you that the F# type inference algorithm found a place in your code where the actual type of what you wrote does not match the type that is expected in that location. It also tells you what the two mismatching types are. For example, say you write something like this:
let concat (llst:'a list list) : 'a list =
llst
You will get the error you are getting on the second line, because the type of llst is 'a list list (the compiler knows this from the type annotation you give on line 1), but the expected type is the same as the result type of the function which is 'a list - also specified by your type annotation.
So, to help you find the issue - look at the exact place where you are getting an error and try to infer why compiler thinks that the actual type is 'a list list and try to understand why it expects 'a list as the type that should be in this place.
This is correct:
let concat (llst:'a list list) : 'a list =
List.concat llst
However, it's really equivalent to let concat = List.concat
This, however, doesn't compile, the elements of the lists need to be of the same type:
let llst = [ [1] ; [2;3] ; ['d';'e';'f'] ]
This also is problematic:
List.iter (fun elem -> printf "%d " elem) concat
List.iter has two arguments and the second one needs to be a List. However in your case you are (as per compiler error) providing your concat function which is a a' List List -> a' List.
What I suspect you meant to do, is apply the concat function to your llist first:
List.iter (fun elem -> printf "%d " elem) (concat llist)
// or
llist
|> concat
|> List.iter (fun elem -> printf "%d " elem)
However, all of this is perhaps missing the point of the exercise. What perhaps you need to do is implement some simple recursion based on the empty / non-empty state of your list, ie. fill in the blanks from here:
let rec myconcat acc inlist =
match inlist with
| [] -> ??
| elt :: tail -> ??
I'm trying to do this exercise:
I'm not sure how to use Type in F#, in F# interactive, I wrote type term = Term of float *int, Then I tried to create a value of type term by let x: term = (3.5,8);;But it gives an error.
Then I tried let x: term = Term (3.5,8);; and it worked. So Why is that?
For the first function, I tried:
let multiplyPolyByTerm (x:term, p:poly)=
match p with
|[]->[]
But that gives an error on the line |[]->[] saying that the expression is expecting a type poly, but poly is a in fact a list right? So why is it wrong here? I fixed it by |Poly[]->Poly[]. Then I tried to finish the function by giving the recursive definition of multiplying each term of the polynomial by the given term: |Poly a::af-> This gives an error so I'm stuck on trying to break down the Poly list.
If anyone has suggestion on good readings about Type in F#, please share it.
I got all the methods now, However,I find myself unable to throw an exception when the polynomial is an empty list as the base case of my recursive function is an empty list. Also, I don't know how to group common term together, Please help, Here are my codes:
type poly=Poly of (float*int) list
type term = Term of float *int
exception EmptyList
(*
let rec mergeCommonTerm(p:poly)=
let rec iterator ((a: float,b: int ), k: (float*int) list)=
match k with
|[]->(a,b)
|ki::kf-> if b= snd ki then (a+ fst ki,b)
match p with
|Poly [] -> Poly []
|Poly (a::af)-> match af with
|[]-> Poly [a]
|b::bf -> if snd a =snd b then Poly (fst a +fst b,snd a)::bf
else
*)
let rec multiplyPolyByTerm (x:term, p:poly)=
match x with
| Term (coe,deg) -> match p with
|Poly[] -> Poly []
|Poly (a::af) -> match multiplyPolyByTerm (x,Poly af) with
|Poly recusivep-> Poly ((fst a *coe,snd a + deg)::recusivep)
let rec addTermToPoly (x:term, p:poly)=
match x with
|Term (coe, deg)-> match p with
|Poly[] -> Poly [(coe,deg)]
|Poly (a::af)-> if snd a=deg then Poly ((fst a+coe,deg)::af)
else match addTermToPoly (x,Poly af) with
|Poly recusivep-> Poly (a::recusivep)
let rec addPolys (x:poly, y: poly)=
match x with
|Poly []->y
|Poly (xh::xt)-> addPolys(Poly xt,addTermToPoly(Term xh, y))
let rec multPolys (x:poly,y:poly)=
match x with
|Poly []-> Poly[]
|Poly (xh::xt)->addPolys (multiplyPolyByTerm(Term xh,y),multPolys(Poly xt,y))
let evalTerm (values:float) (termmm : term) :float=
match termmm with
|Term (coe,deg)->coe*(values**float(deg))
let rec evalPoly (polyn : poly, v: float) :float=
match polyn with
|Poly []->0.0
|Poly (ph::pt)-> (evalTerm v (Term ph)) + evalPoly (Poly pt,v)
let rec diffPoly (p:poly) :poly=
match p with
|Poly []->Poly []
|Poly (ah::at)-> match diffPoly (Poly at) with
|Poly [] -> if snd ah = 0 then Poly []
else Poly [(float(snd ah)*fst ah,snd ah - 1)]
|Poly (bh::bt)->Poly ((float(snd ah)*fst ah,snd ah - 1)::bh::bt)
As I mentioned in a comment, reading https://fsharpforfunandprofit.com/posts/discriminated-unions/ will be very helpful for you. But let me give you some quick help to get you unstuck and starting to solve your immediate problems. You're on the right track, you're just struggling a little with the syntax (and operator precedence, which is part of the syntax).
First, load the MSDN operator precedence documentation in another tab while you read the rest of this answer. You'll want to look at it later on, but first I'll explain a subtlety of how F# treats discriminated unions that you probably haven't understood yet.
When you define a discriminated union type like poly, the name Poly acts like a constructor for the type. In F#, constructors are functions. So when you write Poly (something), the F# parser interprets this as "take the value (something) and pass it to the function named Poly". Here, the function Poly isn't one you had to define explicitly; it was implicitly defined as part of your type definition. To really make this clear, consider this example:
type Example =
| Number of int
| Text of string
5 // This has type int
Number 5 // This has type Example
Number // This has type (int -> Example), i.e. a function
"foo" // This has type string
Text "foo" // This has type Example
Text // This has type (string -> Example), i.e. a function
Now look at the operator precedence list that you loaded in another tab. Lowest precedence is at the top of the table, and highest precedence is at the bottom; in other words, the lower something is on the table, the more "tightly" it binds. As you can see, function application (f x, calling f with parameter x) binds very tightly, more tightly than the :: operator. So when you write f a::b, that is not read as f (a::b), but rather as (f a)::b. In other words, f a::b reads as "Item b is a list of some type which we'll call T, and the function call f a produces an item of type T that should go in front of list b". If you instead meant "take the list formed by putting item a at the head of list b, and then call f with the resulting list", then that needs parentheses: you have to write f (a::b) to get that meaning.
So when you write Poly a::af, that's interpreted as (Poly a)::af, which means "Here is a list. The first item is a Poly a, which means that a is a (float * int) list. The rest of the list will be called af". And since the value your passing into it is not a list, but rather a poly type, that is a type mismatch. (Note that items of type poly contain lists, but they are not themselves lists). What you needed to write was Poly (a::af), which would have meant "Here is an item of type poly that contains a list. That list should be split into the head, a, and the rest, af."
I hope that helped rather than muddle the waters further. If you didn't understand any part of this, let me know and I'll try to make it clearer.
P.S. Another point of syntax you might want to know: F# gives you many ways to signal an error condition (like an empty list in this assignment), but your professor has asked you to use exception EmptyList when invalid input is given. That means he expects your code to "throw" or "raise" an exception when you encounter an error. In C# the term is "throw", but in F# the term is "raise", and the syntax looks like this:
if someErrorCondition then
raise EmptyList
// Or ...
match listThatShouldNotBeEmpty with
| [] -> raise EmptyList
| head::rest -> // Do something with head, etc.
That should take care of the next question you would have needed to ask. :-)
Update 2: You've edited your question to clarify another issue you're having, where your recursive function boils down to an empty list as the base case — yet your professor asked you to consider an empty list as an invalid input. There are two ways to solve this. I'll discuss the more complicated one first, then I'll discuss the easier one.
The more complicated way to solve this is to have two separate functions, an "outer" one and an "inner" one, for each of the functions you have been asked to define. In each case, the "outer" one checks whether the input is an empty list and throws an exception if that's the case. If the input is not an empty list, then it passes the input to the "inner" function, which does the recursive algorithm (and does NOT consider an empty list to be an error). So the "outer" function is basically only doing error-checking, and the "inner" function is doing all the work. This is a VERY common approach in professional programming, where all your error-checking is done at the "edges" of your code, while the "inner" code never has to deal with errors. It's therefore a good approach to know about — but in your particular case, I think it's more complicated than you need.
The easier solution is to rewrite your functions to consider a single-item list as the base case, so that your recursive functions never go all the way to an empty list. Then you can always consider an empty list to be an error. Since this is homework I won't give you an example based on your actual code, but rather an example based on a simple "take the sum of a list of integers" exercise where an empty list would be considered an error:
let rec sumNonEmptyList (input : int list) : int =
match input with
| [] -> raise EmptyList
| [x] -> x
| x::rest -> x + sumNonEmptyList rest
The syntax [x] in a match expression means "This matches a list with exactly one item in it, and assigns the name x to the value of that item". In your case, you'd probably be matching against Poly [] to raise an exception, Poly [a] as the base case, and Poly (a::af) as the "more than one item" case. (That's as much of a clue as I think I should give you; you'll learn better if you work out the rest yourself).
Upon covering the predefined datatypes in f# (i.e lists) and how to sum elements of a list or a sequence, I'm trying to learn how I can work with user defined datatypes. Say I create a data type, call it list1:
type list1 =
A
| B of int * list1
Where:
A stands for an empty list
B builds a new list by adding an int in front of another list
so 1,2,3,4, will be represented with the list1 value:
B(1, B(2, B(3, B(4, A))))
From the wikibook I learned that with a list I can sum the elements by doing:
let List.sum [1; 2; 3; 4]
But how do I go about summing the elements of a user defined datatype? Any hints would be greatly appreciated.
Edit: I'm able to take advantage of the match operator:
let rec sumit (l: ilist) : int =
match l with
| (B(x1, A)) -> x1
| (B(x1, B(x2, A))) -> (x1+x2)
sumit (B(3, B(4, A)))
I get:
val it : int = 7
How can I make it so that if I have more than 2 ints it still sums the elemets (i.e. (B(3, B(4, B(5, A)))) gets 12?
One good general approach to questions like this is to write out your algorithm in word form or pseudocode form, then once you've figured out your algorithm, convert it to F#. In this case where you want to sum the lists, that would look like this:
The first step in figuring out an algorithm is to carefully define the specifications of the problem. I want an algorithm to sum my custom list type. What exactly does that mean? Or, to be more specific, what exactly does that mean for the two different kinds of values (A and B) that my custom list type can have? Well, let's look at them one at a time. If a list is of type A, then that represents an empty list, so I need to decide what the sum of an empty list should be. The most sensible value for the sum of an empty list is 0, so the rule is "I the list is of type A, then the sum is 0". Now, if the list is of type B, then what does the sum of that list mean? Well, the sum of a list of type B would be its int value, plus the sum of the sublist.
So now we have a "sum" rule for each of the two types that list1 can have. If A, the sum is 0. If B, the sum is (value + sum of sublist). And that rule translates almost verbatim into F# code!
let rec sum (lst : list1) =
match lst with
| A -> 0
| B (value, sublist) -> value + sum sublist
A couple things I want to note about this code. First, one thing you may or may not have seen before (since you seem to be an F# beginner) is the rec keyword. This is required when you're writing a recursive function: due to internal details in how the F# parser is implemented, if a function is going to call itself, you have to declare that ahead of time when you declare the function's name and parameters. Second, this is not the best way to write a sum function, because it is not actually tail-recursive, which means that it might throw a StackOverflowException if you try to sum a really, really long list. At this point in your learning F# you maybe shouldn't worry about that just yet, but eventually you will learn a useful technique for turning a non-tail-recursive function into a tail-recursive one. It involves adding an extra parameter usually called an "accumulator" (and sometimes spelled acc for short), and a properly tail-recursive version of the above sum function would have looked like this:
let sum (lst : list1) =
let rec tailRecursiveSum (acc : int) (lst : list1) =
match lst with
| A -> acc
| B (value, sublist) -> tailRecursiveSum (acc + value) sublist
tailRecursiveSum 0 lst
If you're already at the point where you can understand this, great! If you're not at that point yet, bookmark this answer and come back to it once you've studied tail recursion, because this technique (turning a non-tail-recursive function into a tail-recursive one with the use of an inner function and an accumulator parameter) is a very valuable one that has all sorts of applications in F# programming.
Besides tail-recursion, generic programming may be a concept of importance for the functional learner. Why go to the trouble of creating a custom data type, if it only can hold integer values?
The sum of all elements of a list can be abstracted as the repeated application of the addition operator to all elements of the list and an accumulator primed with an initial state. This can be generalized as a functional fold:
type 'a list1 = A | B of 'a * 'a list1
let fold folder (state : 'State) list =
let rec loop s = function
| A -> s
| B(x : 'T, xs) -> loop (folder s x) xs
loop state list
// val fold :
// folder:('State -> 'T -> 'State) -> state:'State -> list:'T list1 -> 'State
B(1, B(2, B(3, B(4, A))))
|> fold (+) 0
// val it : int = 10
Making also the sum function generic needs a little black magic called statically resolved type parameters. The signature isn't pretty, it essentially tells you that it expects the (+) operator on a type to successfully compile.
let inline sum xs = fold (+) Unchecked.defaultof<_> xs
// val inline sum :
// xs: ^a list1 -> ^b
// when ( ^b or ^a) : (static member ( + ) : ^b * ^a -> ^b)
B(1, B(2, B(3, B(4, A))))
|> sum
// val it : int = 10
I have an assignment here that I'm struggling with:
type multimap<'a,'b when 'a:comparison and 'b:comparison> = MMap of Map<'a, list<'b>>
The assignment states that
We define the canonical representation of a multimap to be the representation where the elements in the
value-lists are ordered.
Declare a function canonical: multimap<'a,'b> -> multimap<'a,'b> when 'a : comparison and 'b : comparison
where canonical m returns the canonical representation of m.
Right now I have:
let toOrderedList (mm:multimap<'a,'b>) =
match mm with
| MMap m ->
I don't know how to pattern match on this. Any help? :3
ok, just to give this an answer the function you are looking for can be written like this:
let cannonical (MMap m) =
m
|> Map.map (fun _ vs -> List.sort vs)
|> MMap
this deconstructs the multimap right in the argument definition (pattern-matching) and then pipes the Map<> m through - sorting the lists with Map.map and finally wrapping it back into mulitmap using the constructor MMap
In functional languages (using F#), I am struggling to find a balance between the advantages of functional composition with single-responsibility and getting the performance of single iteration over sequences. Any code pattern suggestions / examples for achieving both?
I don't have a solid background in computational theory and I run into this general pattern over and over: Iterating over a collection and wanting to do side-effects while iterating to avoid further iterations over the same collection or its result set.
A typical example is a "reduce" or "filter" function: There are many times while filtering that I want to take an additional step based on the filter's result, but I'd like to avoid a second enumeration of the filtered results.
Let's take input validation as a simple problem statement:
Named input array
Piped to an "isValid" function filter
Side-effect: Log invalid input names
Pipe valid inputs to further execution
Problem Example
In F#, I might initially write:
inputs
// how to log invalid or other side-effects without messing up isValid??
|> Seq.filter isValid
|> execution
Solution Example #1
With an in-line side-effect, I need something like:
inputs
|> Seq.filter (fun (name,value) ->
let valid = isValid (name,value)
// side-effect
if not valid then
printfn "Invalid argument %s" name
valid
|> execution
Solution Example #2
I could use tuples to do a more pure separation of concerns, but requiring a second iteration:
let validationResults =
inputs
// initial iteration
|> Seq.filter (fun (name,value) ->
let valid = isValid (name,value)
(name,value,valid)
|> execution
// one example of a 2nd iteration...
validationResults
|> Seq.filter (fun (_,_,valid) -> not valid)
|> Seq.map (fun (name,_,_) -> printfn "Invalid argument %s" name)
|> ignore
// another example of a 2nd iteration...
for validationResult in validationResults do
if not valid then
printfn "Invalid argument %s" name
Update 2014-07-23 per Answer
I used this as the solution per the answer. The pattern was to use an aggregate function containing the conditional. There are probably even more elegantly concise ways to express this...
open System
let inputs = [("name","my name");("number","123456");("invalid","")]
let isValidValue (name,value) =
not (String.IsNullOrWhiteSpace(value))
let logInvalidArg (name,value) =
printfn "Invalid argument %s" name
let execution (name,value) =
printfn "Valid argument %s: %s" name value
let inputPipeline input =
match isValidValue input with
| true -> execution input
| false -> logInvalidArg input
inputs |> Seq.iter inputPipeline
Following up on my other answer regarding composition of logging and other side-effects in F#, in this example, you can write a higher-level function for logging, like this:
let log f (name, value) =
let valid = f (name, value)
if not valid then
printfn "Invalid argument %s" name
valid
It has this signature:
f:(string * 'a -> bool) -> name:string * value:'a -> bool
So you can now compose it with the 'real' isValid function like this:
inputs
|> Seq.filter (log isValid)
|> execution
Since the isValid function has the signature name:'a * value:int -> bool it fits the f argument for the log function, and you can partially apply the log function as above.
This doesn't address your concern of iterating the sequence only once (which, for an array, is very cheap anyway), but is, I think, easier to read and clearer:
let valid, invalid = Array.partition isValid inputs
for name, _ in invalid do printfn "Invalid argument %s" name
execution valid