Is traverseBind a recognized FP concept? - functional-programming

I have a function f: 'a -> Async<'b option> that I want to call with 'a option instead of 'a. Now, if I had a function g that returned Async<'b> instead of f's Async<'b option>, I could write a standard traverse implementation and I would then have Async<'b option> at the end. But if I use traverse with f, the result is Async<'b option option>.
It seems to me I need something like this:
module Option =
let traverseBindAsync (f: 'a -> Async<'b option>) (opt: 'a option) : Async<'b option> =
async {
match opt with
| None -> return None
| Some x -> return! f x
}
I don't think traverseBind is a recognized concept (no search results). Is it known under another name, or alternatively, is there another way to think about this in terms of recognized FP concepts one can express in F#? If so, could I use those concepts in a way that is more or less as syntactically concise as the above Option.traverseBindAsync?

I'm not aware of any standard name for a function of a type like this. However, there are two changes you can do to the code that might be somewhat revealing. First, you can implement it without the use of the async block, just by using either f x or by returning async.Unit(None), i.e. an asynchronous computation that immediately returns None:
let traverseBindAsync (f: 'a -> Async<'b option>) (opt: 'a option) : Async<'b option> =
match opt with
| None -> async.Return None
| Some x -> f x
Now you can also rewrite this as doing Option.map on the input and using async.Return(None) as the default value when the input option (and therefore also the result of the map operation) is None:
let traverseBindAsync (f: 'a -> Async<'b option>) (opt: 'a option) : Async<'b option> =
opt |> Option.map f |> Option.defaultValue (async.Return None)
I don't think this has any name, but you can think of your function as Option.map with a particular default value when the input is not available.

Related

Why are my types not working out? (Use of type 'a pred = 'a -> bool)

I have been stuck on this question for a while. I've been editing and reviewing and changing the types for a while but I can't get the type checker to accept what I am doing, probably because I don't fully understand the error/where I am going wrong on this. I am working with the type:
type 'a pred = 'a -> bool
I believe this means I can use 'a pred as a shortcut to mean 'a -> bool, so an int going to result in a bool in my case, but I don't fully get how to implement it because I can't find many examples on this online which I have checked for.
My latest version is below, but I am getting a few errors from the checker, including Error: operator and operand do not agree. Would someone be able to explain where my error is, and why?
Edit: I now think there is a mismatch between this function and the rest of the code. The rest of the code requires it to be an 'a, polymorphic, while here I am assuming it is an int. However, I'm not sure how to do this function (check if odd) while keeping it a polymorphic type.
fun isOdd (p : int) : bool =
case p
of 1 => true
| 0 => false
| _ => isOdd (p - 2)
I believe this means I can use 'a pred as a shortcut to mean 'a -> bool
That is correct.
In the case of your isOdd predicate, it is an int pred:
> val isOdd = fn : int -> bool
- isOdd : int pred;
> val it = fn : int -> bool
Perhaps your misconception lies in the fact that in spite of expressing : int pred, the result in the REPL is still described as int -> bool? This is because we have only defined a type alias, and those tend reduce to their non-aliased form in SML.
Or perhaps your misconception lies in the 'a reducing to some concrete value? You can operate with 'a pred by not referring to concrete values of 'a. For example, if you want to filter an 'a list for only values that are true for a given 'a pred, then the standard function List.filter will have the type:
- List.filter : 'a pred -> 'a list -> 'a list;
> val 'a it = fn : ('a -> bool) -> 'a list -> 'a list
I'm not sure how to do this function (check if odd) while keeping it a polymorphic type.
I'm not sure, either.
Oddness is a property of integers, not arbitrary types 'a.
You would need to extend the meaning of "odd" to any type first. Then you would need some kind of overloading, since the oddness of every type presumably isn't determined by the same mechanism. I'm pretty sure this is a side-track caused by one or two confusions.

How to iterate a stream in Ocaml

I am trying to iterate through a stream in order to print the content.
type 'a stream = Nil | Cons of 'a * 'a stream thunk and 'a thunk = unit -> 'a
This is where my function is called
|> iter_stream ~f:(fun (f,c,l) -> printf "%s %s %s\n" f c l)
And this is the type
let rec iter_stream st ~f
(* val iter_stream : 'a stream -> ('a -> unit) -> unit *)
I can't seem to find any examples on how to implement it. The only idea I have is to think about it like a list which is obviously wrong since I get type errors.
let rec iter_stream st ~f =
match st with
| None -> ()
| Some(x, st') -> f x; iter_stream st' ~f
Your stream is extremely similar to a list, except that you need to call a function to get the tail of the list.
Your proposed code has many flaws. The main two flaws that I see are:
You're using the constructors None and Some while a stream has constructors Nil and Cons.
You're not calling a function to get the tail of the stream. Note that in Cons (a, b), b is a "stream thunk", i.e., it's a function that you can call to get a stream.
(Perhaps these are the only two flaws :-)
I hope this helps.

Given several Option<'a> values, is there a well-known pattern for chaining several 'a -> 'b -> 'b functions?

I have a series of functions 'arg -> 'entity -> 'entity to update an immutable entity.
I have a series of corresponding 'arg option arguments where if the argument is Some, I should call the corresponding update function.
I have currently implemented it like this:
// General utility function
// ('a -> 'b -> 'b) -> 'a option -> 'b -> 'b
let ifSome f argOpt entity =
match argOpt with
| Some arg -> f arg entity
| None -> entity
// Function that accepts several option parameters
// (callbackUrl and authHeader are wrapped in option)
let updateWebhook callbackUrl authHeader webhook =
webhook
|> ifSome Webhook.setCallbackUrl callbackUrl
|> ifSome Webhook.setAuthHeader authHeader
I like how simple it is, but as is often the case with my homegrown functional solutions (particularly when the generic function is more generic than suggested by the parameter names I came up with), I get the feeling that this is just a special case of a more general functional concept - that I could use some existing abstractions to perform the same task. I therefore wonder:
Is this a recognized functional pattern? If so, does it have a name, and can I read more about it somewhere?
If not, is there a (hopefully similarly simple) alternative that accomplishes the same using "well-known" functional abstractions/patterns?
This is just Option.fold (or more precisely in this case Option.foldBack). Folds are more generally known as catamorphisms.
let updateWebhook callbackUrl authHeader webhook =
webhook
|> Option.foldBack Webhook.setCallbackUrl callbackUrl
|> Option.foldBack Webhook.setAuthHeader authHeader

Can I annotate the complete type of a `fun` declaration?

In a learning environment, what are my options to provide type signatures for functions?
Standard ML doesn't have top-level type signatures like Haskell. Here are the alternatives I have considered:
Module signatures, which require either a separate signature file, or the type signature being defined in a separate block inside the same file as the module itself. This requires the use of modules, and in any production system that would be a sane choice.
Modules may seem a little verbose in a stub file when the alternative is a single function definition. They both introduce the concept of modules, perhaps a bit early,
Using val and val rec I can have the complete type signature in one line:
val incr : int -> int =
fn i => i + 1
val rec map : ('a -> 'b) -> 'a list -> 'b list =
fn f => fn xs => case xs of
[] => []
| x::ys => f x :: map f ys
Can I have this and also use fun?
If this is possible, I can't seem to get the syntax right.
Currently the solution is to embed the argument types and the result type as such:
fun map (f : 'a -> 'b) (xs : 'a list) : 'b list =
raise Fail "'map' is not implemented"
But I have experienced that this syntax gives the novice ML programmer the impression that the solution either cannot or should not be updated to the model solution:
fun map f [] = []
| map f (x::xs) = f x :: map f xs
It seems then that the type signatures, which are supposed to aid the student, prevents them from pattern matching. I cannot say if this is because they think that the type signatures cannot be removed or if they should not be removed. It is, of course, a matter of style whether they should (and where), but the student should be enabled to explore a style of type inference.
By using a let or local bound function, and shadowing
you can declare the function, and then assign it to a value.
using local for this is more convenient, since it has the form:
local decl in decl end, rather than let decl in expr end,
meaning let's expr, wants a top-level argument f
val map = fn f => let fun map = ... in map end
I don't believe people generally use local, anymore primarily because modules can do anything that local can, and more, but perhaps it is worth considering it as an anonymous module, when you do not want to explain modules yet.
local
fun map (f : 'a -> 'b) (x::rest : 'a list) : 'b list
= f x :: map f rest
| map _ ([]) = []
in
val (map : ('a -> 'b) -> 'a list -> 'b list) = map;
end
Then when it comes time to explain modules, you can declare the structure inside the local, around all of the declarations,
and then remove the local, and try to come up with a situation, where they have coded 2 functions, and it's more appropriate to replace 2 locals, with 1 structure.
local
structure X = struct
fun id x = x
end
in val id = X.id
end
perhaps starting them off with something like the following:
exception ReplaceSorryWithYourAnswer
fun sorry () = raise ReplaceSorryWithYourAnswer
local
(* Please fill in the _'s with the arguments
and the call to sorry() with your answer *)
fun map _ _ = sorry ()
in
val map : ('a -> 'b) -> ('a list) -> ('b list) = map
end

Using Map.update in OCaml

I am attempting to change the value of a key in a map I made in OCaml:
module TestMap = Map.Make(String);;
let m = TestMap.empty;;
let m = TestMap.add "Chris" 1 m ;;
let m = TestMap.add "Julie" 4 m;;
This compiles file, but when I try to update the value at key Julie with:
let m = TestMap.update "Julie" 10 m;;
I get an error from the compiler:
Error: This expression has type int but an expression was expected of type
'a option -> 'a option
I'm guessing that I'm maybe using the function incorrectly. I'm finding the documentation for Map.update pretty hard to understand:
val update : key -> ('a option -> 'a option) -> 'a t -> 'a t
Is my syntax or are my arguments incorrect?
The update function works in a way different from what you think
key -> ('a option -> 'a option) -> 'a t -> 'a t
You see that second argument is a function which takes an 'a option and returns an 'a option so you don't directly update with a new value but rather pass a function which returns the new value, according to the previous one, eg:
let m = TestMap.update "Julie" (fun _ -> Some 10) m;;
This because, as documentation states, the passed 'a option tells you if there was a mapping for the key and the returned 'a option allows you to change it or even remove it (through None).
If you need just to update a mapping you can use Map.add again, there's no need to use more advanced Map.update.

Resources