Since partially applied functions are instances of the MonadReader, why is the following code incorrect?
runReader (\x -> x + 2) 4
or even
runReader (\x -> pure $ x + 2) 4
Being an instance of MonadReader allows you to use the "reader operations" (local, ask, asks), but runReader is explicitly for running a type of Reader.
So for example, you can do this because of monadReaderFun:
readerFunction :: Int -> Int
readerFunction = do
x <- ask
pure (x + 2)
But there's no need to "run" it, the way you do with a Reader or ReaderT typed value.
Related
My question
I'm referring to a function which does essentially the following (modulo const, &, perfect forwarding, or whatever is appropriate):
auto constexpr dollar = [](auto f, auto x){ return f(x); }; // Why calling it "dollar"? Keep reading...
Is such a function expressable only via Boost.Hana?
Why did I think of it?
In Haskell, such a function exists, and it's called ($) ($ in infix form), and its definition is the following (source code)
($) :: forall r a (b :: TYPE r). (a -> b) -> a -> b
f $ x = f x
and you could write the second line simply as either of the following
(f $) = f
($) f = f
where the second form makes it apparent that ($) is essentially the same as the id (identity function)
id :: a -> a
id x = x
just with a signature that enforces that the first argument be of function type a -> b and the second argument of type a.
Indeed, applying f to x in Haskell can be done also by writing this
f `id` x
i.e. using `id` instead of $.¹
How is that related to Hana?
Since Hana does offer an id function, I was wondering if that (maybe together with something else) can be used to define a function application utility without manually writing the lambda at the top of this post.
The difficult part
The hard part here is that when you write f `id` x in Haskell, there's not much really a point in arguing on whether you're passing 1 or 2 arguments to id, because all functions are curried by default.
That's not true in C++. For instance I can do this:
#include <boost/hana/functional/id.hpp>
#include <iostream>
using boost::hana::id;
int main() {
auto plus1 = [](int x){ return x + 1; };
std::cout << id(plus1)(3) << std::endl; // prints 4
}
which looks a lot like id is curried and is being given two inputs one after the other rather than together, but that's not true. It's just that id(plus1) is returning plus1, which is fed with 3. I don't know how to get the following (which would be equivalent to plus1 `id` 3 or id plus1 3 in Haskell) work:
std::cout << id(plus1, 3) << std::endl; // doesn't even compile obviously
The true origin of the puzzle
After reading To Mock a Mockingbird, I wondered: "How do I implement the Thrush in C++ only with Boost.Hana?" (And the Thrush is the boost::hana::flipped version of the function application operator.)
¹In reality it's not exactly the same if want to write chains of applications, as the two operators have different associativity, so f $ g $ x == f `id` (g `id` x), but this is not relevant to the question, I believe.
I'm just trying to get monads, so bear with me if I ask a bad question, but...
If monads only require:
(a -> M a), where M is the monadic type constructor, and
(M a -> (a -> M b) -> M b), which is the bind operation (which I understand as mapping a monad onto a non-monadic to monadic value function)
...doesn't this mean that:
(M a -> a) and
(M (M a) -> M a) are not implicitly required?
Won't this usually cause a problem?
Suppose we have a set of functions, S, which all have the type (x -> y), where x and y are arbitrary types.
Now, suppose I program using a set of monadic functions M, where their types are x -> M y.
Doesn't this mean that once I turn a type into M y, I can't use any of the (x -> y) functions? Or, can I assume that I can do (M x -> (x -> y) -> (y -> M y) -> M y)?
Furthermore, don't we usually want to extract the original type when programming? When switching between something, like async a -> a or maybe a -> a... Isn't that a common operation? I can definitely see the case where somebody wants to optimize a monad out if they see it as negligible (e.g. a logging monad).
Additionally, what about layered monads without flattening? I understand that lists can be seen as monads where restricting flattening is a clear and logical choice, but what about the hypothetical case of async (async a) monadic values where async has no flatten function? Does bind only imply one layer of "monadic reduction" where we can often assume that (M a -> (a -> M a) -> M a) can often be seen as (M a -> (M a -> a) -> (a -> M a) -> M a), and (M M a -> (a -> M a) -> M a or M M a) may not work? Is there a true difference between flattening and non-flattening monads?
Won't this usually cause a problem?
You might say that this is "by design". One of the possible uses is IO; once you have a value tainted with IO, you have to "bubble up"; you can't hide the fact that a function is doing IO under a pure value.
wouldn't that mean I either have to manually convert each (a -> b) -> (a -> M b) by applying a monadic constructor somewhere?
This is easier than you think because every Monad is also a Functor and an Applicative Functor:
randomDice :: IO Int
randomDice = randomRIO (1,6)
cheat :: Int -> Int
cheat = (+1)
main = do
dice <- randomDice
dice' <- cheat <$> randomDice
Having all of the fmap, <$>, liftA/liftM and pure/return machinery at our disposal, it makes it very simple to easily use pure functions in the monadic contexts.
(M (M a) -> M a) is not implicitly required
That one is false. You only need bind to implement it.
join :: (Monad m) => m (m a) -> m a
join x = x >>= id
I am studying for a test, and one of the practice problems is to write a function of the type (int->int)->(int->int). The provided answer
fun x y -> (x 1) + y
But when I put something like
let funct x y = (x 1) + y;;
it spits out (int->int)->int->int. Is this any different from the version with the extra parentheses. If yes how, if no why not?
No different, -> is right-associative. Same reason why (1 - 2) - (3 - 4) is same as 1 - 2 - (3 - 4) (subtraction being left-associative, the effect is mirrored).
This hinges on the existence of currying in OCaml, i.e. the fact that a function of one parameter that returns a function of one parameter is indistinguishable from function of two parameters - i.e. f 1 2 is same as (f 1) 2.
I'm working with a custom implementation of vectors as functions whose domain is a finite "index set" of natural numbers, and whose image is of some type on which one can define a maximum, usually real. E.g. I could have a two-dimensional vector v with v 1 = 2.7 and v 3 = 4.2.
On such vectors I'd like to define an "arg max" like operator, which tells me the index of the maximum component, 3 in the example of v above. I'm saying "the" index because the "arg max" like operator will additionally accept a tie-breaking function to be applied to components with values. (The background is bids in auctions.)
I know that Max on finite sets is defined using fold1 (of which I do not yet understand how it works). I tried this, which was accepted in itself, but then didn't work for the other things I wanted to do:
fun arg_max_tb :: "index_set ⇒ tie_breaker ⇒ (real vector) ⇒ nat"
where "arg_max_tb N t v = fold1
(λ x y . if (v x > v y) then x (* component values differ *)
else if (v x = v y ∧ t x y) then x (* tie-breaking needed *)
else y) N"
Note that furthermore I would like to prove certain properties of my "arg max" like operator, which will likely require induction. I know that there is the rule finite_ne_induct for induction over finite sets. OK, but I would also like to be able to define my operator in such a way that it can be evaluated (e.g. when trying with concrete finite sets), but evaluating
value "arg_max_tb {1::nat} (op >) (nth [27::real, 42])"
with expected return value 1 gives me the following error:
Wellsortedness error
(in code equation arg_max_tb ?n ?t ?v \equiv
fold1 (\lambda x y. if ord_real_inst.less_real (?v y) (?v x) then ...) ?n):
Type nat not of sort enum
No type arity nat :: enum
Therefore I resorted to converting my finite sets to lists. On lists I have been able to define the operator, and to prove some of its properties (can share the code if it's of interest) by induction using list_nonempty_induct.
The working list-based definition looks as follows:
fun arg_max_l_tb :: "(nat list) ⇒ tie_breaker ⇒ (real vector) ⇒ nat"
where "arg_max_l_tb [] t v = 0"
(* in practice we will only call the function
with lists of at least one element *)
| "arg_max_l_tb [x] t v = x"
| "arg_max_l_tb (x # xs) t v =
(let y = arg_max_l_tb xs t v in
if (v x > v y) then x (* component values differ *)
else if (v x = v y ∧ t x y) then x (* tie-breaking needed *)
else y)"
fun arg_max_tb :: "index_set ⇒ tie_breaker ⇒ (real vector) ⇒ nat"
where "arg_max_tb N t v = arg_max_l_tb (sorted_list_of_set N) t v"
I didn't succeed to directly define a function over the constructors of a finite set. The following doesn't work:
fun arg_max_tb :: "index_set ⇒ tie_breaker ⇒ (real vector) ⇒ participant"
where "arg_max_tb {} t b = 0"
| "arg_max_tb {x} t b = x"
| "arg_max_tb (insert x S) t b =
(let y = arg_max_tb S t b in
if (b x > b y) then x
else if (b x = b y ∧ t x y) then x
else y)"
It gives me the error message
Malformed definition:
Non-constructor pattern not allowed in sequential mode.
⋀t b. arg_max_tb {} t b = 0
Could this be because the list constructors are defined as a datatype, whereas finite sets are merely defined as an inductive scheme?
Whatever – do you know of a way of defining this function over finite sets? Either by writing it down directly, or by some fold-like utility function?
Folding over a finite set requires that the result is independent of the order in which the elements of the set are visited, because sets are unordered. Most lemmas about fold1 f therefore assume that the folding operation f is left-commutative, i.e., f a (f b x) = f b (f a x) for all a, b, x.
The function that you supply to fold1 in your first definition does not satisfy this because the tie-breaking function is an arbitrary predicate. For example, take the tie-breaking function %v v'. True. Hence, if you want to stick to this definition, you will have to find sufficient conditions on the tie-breaking first and thread this assumption through all your lemmata.
Your working solution based on a sorted list of the elements avoids this commutatitivity problem. Your last suggestion with pattern matching on {}, {x} and insert x S does not work for two reasons. First, fun can only pattern-match on datatype constructors, so you would have to use function instead; this explains the error message. But then, you also have to prove the equations do not overlap and you will therefore run into the same problem with commutativity again. Additionally, you will not be able to prove termination because S might be infinite.
The well-sortedness error for code generation comes from the setup for fold1. fold1 f A is defined as THE x. fold1Set f A x where fold1Set f A x holds iff x is the result of folding f over A in some order of the elements. To check that all the results are the same, the generated code naively tests for all possible values of x whether fold1Set f A x holds. If it indeed finds just one such value, then it returns that value. Otherwise, it raises an exception. In your case, x is an index, i.e., of type nat which infinitely many values inhabit. Hence, exhaustive testing is not possible. Technically, this translates as nat not being an instance of the type class enum.
Normally, you derive specialised code equations for everything that you define in terms of fold1. See the code generator tutorial on program refinement.
This question really consists of multiple questions.
Defining a function on finite sets
fold / foldl1
The usual recursion combinator is Finite_Set.fold (or fold1). However, to be able to prove anything fold f z S, the result must be independent of the order f is applied to the elements of S.
If f is associative and commutative, you can use Finite_Set.ab_semigroup_mult.fold1_insert and Finite_Set.fold1_singleton to get simp rules for fold1 f S and you should be able to use finite_ne_induct as your induction rule.
Note that the function (I'll call it f) you give to fold1 is only commutative if t is a linear order:
fun arg_max_tb :: "index_set ⇒ tie_breaker ⇒ (real vector) ⇒ nat"
where "arg_max_tb N t v = fold1
(λ x y . if (v x > v y) then x (* component values differ *)
else if (v x = v y ∧ t x y) then x (* tie-breaking needed *)
else y) N"
This is not covered by the existing lemmas on fold1, so you either need to prove a generalized variant of Finite_Set.ab_semigroup_mult.fold1_insert or insert an additional tie-breaker, e.g.
else if (v x = v y ∧ ~t x y ∧ ~t y x ∧ x < y) then x
If t is a linear order, you will be able to remove this additional tie-breaker from the simp rules. Note that this additional tie-breaker is basically what you get from using sorted_list_of_set.
THE / SOME
Your arg_max_tb selects one element of a list with certain properties. This can also be defined directly with the constructs THE x. P x or SOME x. P x (choice operators). The former selects the unique element satisfying the property P (if no unique element exists, the result is undefined), the latter selects some element satisfying the property P (if no such element exists, the result is undefined). Both work for infinite lists, too.
These are often preferable if you don't need executable code.
Getting an executable function
Functions defined by recursion (i.e. primrec, fun or function) are executable by default (if all functions used in their definition are executable, too). THE and SOME can in general only be executed for enumerable domains (this is the error message you got from value -- nat is not enumerable, as it is not finite).
However, you can always give an alternative definition of your function to the code generator. See the Tutorial on Function Definitions, in particular the section about refinement.
If you prefer the formulation with choice operators for proving, but also like your function to be executable, the easiest way might to prove that the definitions of arg_max_tb via choice and sorted_list_of_set are equivalent. Then you can use the [code_unfold] predicate to replace the definition by choice with the (executable) definition by sorted_list_of_set
Just a quick question. I'm wondering if there is a infix function composition operator in OCaml defined in the standard library (or in Jane Street's Core or in Batteries) like the (.) function in Haskell which saves us a lot parentheses since we can write (f . g . h) x instead of the less appealing f (g (h x))).
Thanks folks.
The answer here is the same as for flip :-). Function composition isn't defined in the OCaml standard library. In this case, it isn't something I miss once in a while, I miss it all the time.
The OCaml Batteries Included project defines function composition (in the order you give) using the operator -| in the BatStd module. As lukstafi points out (see below), this operator will apparently change to % in a future release of Batteries. (I've verified this in their source tree.)
As far as I can see, the Jane Street Core project doesn't define a function composition operator. It defines a function compose in the Fn module.
I just want to add that the operator is fairly easy to include, in F# it's simply defined as:
let (<<) f g x = f(g(x));;
which has the type signature: val ( << ) : f:('a -> 'b) -> g:('c -> 'a) -> x:'c -> 'b doing exactly what you need...
(f << g << h) x = f(g(h(x))
so you don't need the batteries project if you don't have to
I'd like to add that the reason it looks like << is, as you might guess, because the >> operator does the opposite:
let (>>) f g x = g(f(x));;
(f >> g >> h) x = h(g(f(x))
There is Fn.compose function in Core, but it is not an infix operator. Also, it is implemented as a regular function and has runtime overhead.
In practice, it is pretty convenient to use pipe operator. It has no runtime overhead as implemented directly in compiler (starting from 4.00). See Optimized Pipe Operators for more details.
Pipe operator is available as '|>' in Core. So, you can rewrite your expression as following: h x |> g |> f
The use of an infix composition operator seems to be discouraged. (see this discussion).
You can write f ## g ## h x instead of f (g (h x))).
In Containers (yet another stdlib replacement for Ocaml), the function composition operator is called % and can be found in the CCFun module:
open Containers
open Fun
let is_zero n = (n = 0)
let nonzeros = List.filter (not % is_zero) [0;1;2;3;0]
Maybe that could help you.
let identite f = f
let (>>) = List.fold_right identite
test:
# let f=fun x-> x+1 and
g=fun x-> x*2 and
h=fun x-> x+3;;
# [f;g;h] >> 2;;
- : int = 11