Change operator precedence for ∘ - julia

I'd like to change the priority of ∘ so that it is applied first. Hence no bracket is needed in the function composition below. Is this possible?
julia> ∘(f,g) = x->f(g(x))
∘ (generic function with 1 method)
julia> (sqrt ∘ abs)(randn())
0.9069709279812338
julia> sqrt ∘ abs(randn())
(::#15) (generic function with 1 method)

Julia is strong at metaprogramming so you have to be able to make your own microlanguage.
I am just beginner at Julia so code below is just my little experiment! (And it is inclomplete because problems with parsing multiple lines )
But maybe it could be inspirational:
module M
macro x(a)
w = r"(\w+)\s*∘\s*(\w+)" # trying to find words around ∘
s = s"(\1 ∘ \2)" # and enclosed them into brackets
b = replace("$a", w, s)
return :(eval(parse($b)))
end
end
import M
M.#x(
sqrt ∘ abs(randn())
)

Related

How do I write Functor and Applicative for Vector-Composition?

I´m trying to learn more about dependent types using IDRIS.
The example I am trying to emulate uses composition of Vectors.
I understand Functor and Applicative implementations for Vectors but I am struggling to implement them for the Composition.
data Vector : Nat -> Type -> Type where
Nil : Vector Z a
(::) : a -> Vector n a -> Vector (S n) a
Functor (Vector n) where
map f [] = []
map f (x::xs) = f x :: map f xs
Applicative (Vector n) where
pure = replicate _
fs <*> vs = zipWith apply fs vs
Now the Composition and Decomposition-Function look like this:
data (:++) : (b -> c) -> (a -> b) -> a -> Type where
Comp : (f . g) x -> (f :++ g) x
unComp : (f :++ g) a -> (f . g) a
unComp (Comp a) = a
User with Vectors it encapsulates a Vector of Vectors.
Now I need an Applicative for the Composition (Vector n) :++ (Vector n).
I can´t even get Functor to work and am mainly trying to see what I´m doing wrong. I tried the following and, since Functor is already implemented for Vectors, that this would work
Functor ((Vector n) :++ (Vector n)) where
map f (Comp []) = Comp []
map f (Comp (x::xs)) = Comp ((f x) :: (map f (Comp xs)))
but the Compiler gives an Error-Message:
When checking an application of constructor Main.:::
Unifying a and Vector (S n) a would lead to infinite value
Isn´t unifying and element of type a and a Vector n a exactly the purpose of (::)?
I am obviously doing something wrong and I can´t get this to work. I also have the feeling it´s probably easy to solve, but after hours of reading and trying I still don´t get it.
If someone could give me advice or explain to me how the Functor and Applicative implementations could look like, I would be very grateful.
Update: Idris 2 now has this builtin. Functor for Compose, Applicative for Compose
I think you can implement a general instance of Functor and Applicative like with Haskell's Compose.
newtype Compose f g a = Compose { getCompose :: f (g a) }
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose x) = Compose (fmap (fmap f) x)
a <$ (Compose x) = Compose (fmap (a <$) x)
instance (Applicative f, Applicative g) => Applicative (Compose f g) where
pure x = Compose (pure (pure x))
Compose f <*> Compose x = Compose (liftA2 (<*>) f x)
liftA2 f (Compose x) (Compose y) =
Compose (liftA2 (liftA2 f) x y)
To answer your specific question (but don't do it this way):
Functor ((Vector n) :++ (Vector n)) where
map f (Comp x) = Comp $ map (map f) x

ASCII alternative to the Julia function composition (∘) operator?

Is there an ASCII alias for the function composition operator in Julia, ∘?
In general, is there a way to find ASCII/Unicode variants of operators?
julia> ∘
∘ (generic function with 2 methods)
^Tried this, ≈ for example has an alternative:
julia> ≈
isapprox (generic function with 8 methods)
For ∘ there is no alternative AFAICT. You can check by running:
julia> methods(∘)
# 3 methods for generic function "∘":
[1] ∘(f) in Base at operators.jl:874
[2] ∘(f, g) in Base at operators.jl:875
[3] ∘(f, g, h...) in Base at operators.jl:876
and opening the respective function definition (if you have a properly configured Julia installation just press e.g. 1 and then CTRL-Q) to get:
function ∘ end
∘(f) = f
∘(f, g) = (x...)->f(g(x...))
∘(f, g, h...) = ∘(f ∘ g, h...)
However, it is easy enough just to write:
const compose = ∘
and now you can use compose(f, g) instead of f ∘ g.
For ≈ and isapprox it is the case that in the code isapprox function is defined and then:
const ≈ = isapprox
definition is added in floatfuncs.jl.

Anonymous recursive functions in OCaml

How do you make an anonymous recursive function (something simple for example factorial n?) I have heard it is possible but no idea how to make it work in OCaml.
let a =
fun x -> ....
I just don't know how to keep it going...
Here is a definition of factorial using only anonymous functions:
let fact =
(fun f -> (fun x a -> f (x x) a) (fun x a -> f (x x) a))
(fun f n -> if n < 2 then 1 else n * f (n - 1))
It requires the use of the -rectypes flag.
Here's a session showing that it works:
$ rlwrap ocaml -rectypes
OCaml version 4.03.0
let fact =
(fun f -> (fun x a -> f (x x) a) (fun x a -> f (x x) a))
(fun f n -> if n < 2 then 1 else n * f (n - 1));;
val fact : int -> int = <fun>
# fact 8;;
- : int = 40320
I cheated somewhat by looking up the Y Combinator here: Rosetta Code: Y Combinator
Update
Disclaimer: you would do better to read up on lambda calculus, fixed points, and the Y Combinator than to get your info from me. I'm not a theorist, just a humble practitioner.
Following the actual computation is almost impossible (but definitely worth doing I'm sure). But at a high level the ideas are like this.
The first line of the definition is the Y Combinator, which in general calculates the fixed point of a function. It so happens that a recursive function is the fixed point of a function from functions to functions.
So the first goal is to find the function whose fixed point is the factorial function. That's the second line of the definition. If you give it a function of type int -> int, it gives you back another function of type int -> int. And if you give it the factorial function, it gives you back the factorial function. This means that the factorial function is its fixed point.
So then when you apply the Y Combinator to this function, you do indeed get the factorial function.
Let me try to expand a bit on Jeffrey Scofield's answer. A non-anonymous recursive definition of the factorial function could be
let rec fact n =
if n < 2 then 1 else n * fact (n - 1)
The first problem you encounter when you try to define an anonymous recursive function is how to do the actual recursive call (fact (n - 1) in our case). For a call we need a name and we do not have a name for an anonymous function. The solution is to use a temporary name. With the temporary name f, the definition body is just
fun n -> if n < 2 then 1 else n * f (n - 1)
This term does not have a type, because the "temporary name" f is unbound. But we can turn it into a value that does have a type by bounding f as well. Let us call the result g:
let g = fun f n -> if n < 2 then 1 else n * f (n - 1)
g is not yet anonymous at the moment, but only because I want to refer to it again.
Observe that g has type (int -> int) -> (int -> int). What we want (the factorial function) will have type (int -> int). So g takes something of the type we want (a function type in this case) and produces something of the same type. The intuition is that g takes an approximation of the factorial function, namely a function f which works for all n up to some limit N and returns a better approximation, namely a function that works for all n up to N+1.
Finally we need something that turns g into an actual recursive definition.
Doing so is a very generic task. Recall that g improves the approximation quality. The final factorial function fact is one which cannot be further improved. So applying g to fact should be the same as just fact. (Actually that is only true from a value point of view. The actual computation inherent in g fact n for some n is different from that of just fact n. But the returned values are the same.) In other words, fact is a fixed point of g. So what we need is something that computes fixed points.
Luckily, there is a single function that does so: The Y combinator. From a value point of view, the Y combinator (let us use y in OCaml, as uppercase is reserved for constructors) is defined by the fact that y g = g (y g) for all g: given some function g, the combinator returns one of its fixed points.
Consequently,
y : (`a -> `a) -> `a
In our case the type variable is instantiated by (int -> int).
One possible way to define y would be
let y = fun g -> (fun x -> g (x x)) (fun x -> g (x x))
but this works only with lazy evaluation (as, I believe, Haskell has). As OCaml has eager evaluation, it produces a stack overflow when used. The reason is that OCaml tries to turn something like y g 8 into
g (y g) 8
g (g (y g)) 8
g (g (g (y g))) 8
...
without ever getting to call g.
The solution is to use deferred computation inside of y:
let y = fun g -> (fun x a -> g (x x) a) (fun x a -> g (x x) a)
One drawback is that y does not work for arbitrary types any more. It only works for function types.
y : ((`b -> `c) -> (`b -> `c)) -> (`b -> `c)
But you asked for recursive definitions of functions anyway, not for recursive definitions of other values. So, our definition of the factorial function is y g with y and g defined as above. Neither y nor g are anonymous yet, but that can be remedied easily:
(fun g -> (fun x a -> g (x x) a) (fun x a -> g (x x) a))
(fun f n -> if n < 2 then 1 else n * f (n - 1))
UPDATE:
Defining y only works with the -rectypes option. The reason is that we apply x to itself.
There is also an "intuitive" way to accomplish anonymous recursion without resorting to Y combinators.
It makes use of a let binding to store the value of a lambda that accepts itself as an argument, so that it can call itself with itself as the first parameter, like so:
let fact = (let fact0 = (fun self n -> if n < 2 then 1 else n * self self (n - 1)) in (fun n -> fact0 fact0 n));;
It's anonymous only to the extent that it is not defined with let rec.

Well-founded recursion using (Acc lt (x-y))

In A Tutorial on[Co-]Inductive Types in Coq on p. 47, a recursive function is defined, where each recursive step uses a well-formedness proposition to show that the recursion terminates.
A function that is called with x makes a recursive call with x-y where y<>0, so it should terminate.
I am not able to enter it into Coq without getting an error. Coq is complaining that the recursion argument is not smaller in the call, while the tutorial claims that it is so.
What am I missing?
I rewrote the code slightly to make it shorter, but I also tried the verbatim definitions in the paper.
First we show that x-y is accessible from x.
Require Import Omega.
Definition minus_decrease:
forall x y, Acc lt x -> x<>0 -> y<>0 -> Acc lt (x-y).
intros x y H Hx Hy.
case H; intro Ha; apply Ha.
omega.
Qed.
Next, when trying to define the function, like this
Definition div_aux :=
fix div_aux (x y:nat) (H:Acc lt x) {struct H}: nat :=
match eq_nat_dec x 0 with
|left _ => 0
|right _ =>
match eq_nat_dec y 0 with
|left _ => 0
|right v => S (div_aux (x-y) y (minus_decrease x y H _ v))
end
end.
then Coq refuses, saying
Recursive call to div_aux has principal argument equal to
"minus_decrease x y H ?156 v" instead of a subterm of "H".
Notice how div_aux x ... calls itself recursively with div_aux (x-y) ..., and (minus_decrease ...) returns a term of type Acc lt (x-y)
How do I use Acc to show that this function actually terminates?
The error seems to be that I ended the definition with Qed. instead of Defined. The following works.
Require Import Omega.
Definition minus_decrease: forall x y, Acc lt x -> x<>0 -> y<>0 -> Acc lt (x-y).
intros x y H Hx Hy.
case H; intro Ha; apply Ha.
omega.
Defined.
Fixpoint div_aux (x y:nat) (H:Acc lt x) {struct H}: nat.
Proof.
refine (if eq_nat_dec x 0
then 0
else if eq_nat_dec y 0
then y
else S (div_aux (x-y) y _)).
apply (minus_decrease _ _ H _H _H0).
Qed.

Why Functor class has no return function?

From categorical point of view, functor is pair of two maps (one between objects and another between arrows of categories), following some axioms.
I have assumed, what every Functor instance is similar to mathematical definition i.e. can map both objects and functions, but Haskell's Functor class has only function fmap which maps functions.
Why so?
UPD In other words:
Every Monad type M has an function return :: a -> M a.
And Functor type F has no function return :: a -> F a, but only F x constructor.
There are two levels: types and values. As objects of Hask are types, you can map them only with type constructors, which have the * -> * kind:
α -> F α (for Functor F),
β -> M β (for Monad M).
Then for a functor you need a map on morphisms (i.e. functions, which are values):
fmap :: (α -> β) -> (F α -> F β)
The important thing is that return :: α -> M α of Monad is not a mapper of a type α to the M α as you might think. According to the mathematical definition of a monad, return corresponds to a natural transformation from Id functor to the M functor. And the Id functor is kind of implicit in Hask. The standard definition of a monad also requires another natural transformation M ◦ M -> M. So translating it to Haskell would look like
class Functor m => Monad m where
return :: Id α -> m α
join :: m (m α) -> m α
(As a side-note: these two natural transformations are actually the unit and multiplication, which make monad a monoid in the category of endofunctors)
The actual definition differs, but is equivalent. See Haskell/wiki on that.
If you take the composition-like operator derived from the standard bind >>= :: m α -> (α -> m β) -> m β:
(>=>) :: Monad m => (α -> m β) -> (β -> m γ) -> (α -> m γ)
f >=> g = \a => f a >>= g
You can see, that it's all actually about the Kleisli category. See also the article on nLab about monads in computer science.
Objects of a category are not the same as objects in a OO programming language (we prefer to call those values in Haskell; what they mean in category theory was discussed here). Rather, the objects of Hask are types. Haskell Functors are endofunctors in Hask, i.e. associate types to types, by the following means:
Prelude> :k Maybe
Maybe :: * -> *
Prelude> :k Int
Int :: *
Prelude> :k Maybe Int
Maybe Int :: *
OTOH, the arrows of Hask are in fact values, of some function type a -> b. These are associated in the following way:
fmap :: ( Functor (f :: t -> f t {- type-level -} ) )
=> (a->b) -> fmap(a->b) {- value-level -}
≡ (a->b) -> (f a->f b)
Though you were using those fancy categorical terms in your question and should be completely satisfied with the existing answers, here is an attempt for a rather trivial explanation:
Suppose there would be a function return (or pure or unit or ...) in the Functor type class.
Now try to define some common instances of Functor: [] (Lists), Maybe, ((,) a) (Tuples with a left component)
Easy enough, eh?
Here are the ordinary Functor instances:
instance Functor [] where
fmap f (x : xs) = f x : fmap xs
fmap _ [] = []
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap _ Nothing = Nothing
instance Functor ((,) a) where
fmap f (x, y) = (x, f y)
What about return for Functor now?
Lists:
instance Functor [] where
return x = [x]
Alright. What about Maybe?
instance Functor Maybe where
return x = Just x
Okay. Now Tuples:
instance Functor ((,) a) where
return x = (??? , x)
You see, it is unknown which value should be filled into the left component of that tuple. The instance declaration says it has a type a but we do not know a value from that type. Maybe the type a is the Unit type with only one value. But if its Bool, should we take True or False? If it is Either Int Bool should we take Left 0 or Right False or Left 1?
So you see, if you had a return on Functors, you could not define a lot of valid functor instances in general (You would need to impose a constraint of something like a FunctorEmpty type class).
If you look at the documentation for Functor and Monad you will see that there are indeed instances for Functor ((,) a) but not for Monad ((,) a). This is because you just can't define return for that thing.
If you have
instance Functor F where
fmap = ...
Then the type constructor F is the action on objects (which are types) taking a type T to the type F T, and fmap is the action on morphisms (which are functions) taking a function f :: T -> U to fmap f :: F T -> F U.
In category theory, a functor maps all the objects from a category to another, but a functor doesn't map the elements in the objects.

Resources