haskell flip simulation problems - function

flip' :: (a -> b -> c) -> (b -> a -> c)
flip' f = g
where g x y = f y x
I want to ask that in the above flip' function , it seems that flip' will return a function named g and g x y share the same value with f y x
however, in " where g x y = f y x " , f y x is a function call and will return a value, g x y will aslo return a value, so does it make sense that " where v2 = v1 "?
I know that the code will work but I want to know more about the way it make this happen.
does anybody has an idea? thank you so much

In where g x y = f y x, g x y is not a function call g with parameters x and y. It is a declaration of the function g as a function taking 2 arguments x and y and evaluation to f y x.
So it means flip' given a function f taking 2 arguments will evaluate to g. g itself being defined as swapping two arguments to call f.

Related

Coq: Defining a special function

I want to define a function f w/ 2 explicit arguments. The types of the arguments and value of f are applications of some g. Suppose the arguments' types are g x y and g z w. The tricky part is that f's value must depend on the unifiability of x and z. Below is a naive attempt at defining f that fails. How should I tackle this?
Inductive A := a | a0 | fa.
Inductive B := b | b0.
Parameter C: Type.
Parameter g: A -> B -> C.
Parameter CT:> C -> Type.
Parameter gab: g a b.
Parameter ga0b: g a0 b.
Definition f {x y z w}(n: g x y)(m: g z w) :=
ltac:(match x with z => exact (g z b) | _ => exact (g fa b) end).
Compute f gab ga0b. (*= g fa b: C*)
Compute f gab gab. (*! = g fa b: C !*)
f's value must depend on the unifiability of x and z
It is impossible to write such a definition. Suppose you could write a function that could tell whether or not two natural numbers unified, call it unify_nat : nat -> nat -> bool. Consider now the functions
F := fun x y : nat => if unify_nat (x + y) (y + x) then True else False
G := fun x y : nat => if unify_nat (x + y) (x + y) then True else False
We can prove, because addition is commutative, that forall x y, F x y = G x y. But then unify_nat (x + y) (y + x) must return true, even though x + y and y + x do not unify.
There are two things you can do: (1) you can ask not if the terms unify, but if they are propositionally equal; and (2) you can write a notation, or an alias, which is like syntactic sugar for a definition.
1.
The command Scheme Equality will generate an equality decision function for most inductive types:
Scheme Equality for A.
Definition f {x y z w}(n: g x y)(m: g z w) :=
if A_beq x z then g z b else g fa b.
Compute f gab ga0b. (*= g fa b: C*)
Compute f gab gab. (*= g a b: C*)
2.
We can create evars with open_constr:(_) and use unification to infer the types of n and m:
Ltac f_tac n m :=
let x := open_constr:(_) in
let y := open_constr:(_) in
let z := open_constr:(_) in
let w := open_constr:(_) in
let n := constr:(n : g x y) in
let m := constr:(m : g z w) in
match x with z => exact (g z b) | _ => exact (g fa b) end.
Notation f n m := (ltac:(f_tac n m)) (only parsing).
Compute f gab ga0b. (*= g fa b: C*)
Compute f gab gab. (*= g a b: C*)

Polymorphic type of functions as parameter in haskell?

Im trying to define the polymorphic type of the following function:
flip f x y = f y x
My thought was the following:
1st parameter of flip, f takes two arguments so (t1 -> t2 -> t3)
2nd parameter of flip, x is of type t1 because of the parameter t1 inside f function.
3rd parameter of flip, y which is of type t3 because of the parameter t3 inside f function.
I don't know the polymorphic type of the overall return.
But when I checked the type in the ghci, I get:
flip :: (t2 -> t1 -> t) -> t1 -> t2 -> t
Can someone please help go through this example was to whats happening here?
Thanks
Your second assumption is wrong:
2nd parameter of flip, x is of type t1 because of the parameter t1 inside f function.
Let us first analyze the function:
flip f x y = f y x
We see that flip has three arguments in the head. So we first make the type:
flip :: a -> (b -> (c -> d))
We will of course now aim to fill in the types. With:
f :: a
x :: b
y :: c
flip f x y :: d
We see on the right hand side:
(f y) x
So that means that f is a function that takes as input y. So that means that a is the same type as c -> e (or shorter a ~ c -> e).
So now:
flip :: (c -> e) -> (b -> (c -> d))
f :: (c -> e)
x :: b
y :: c
Furthermore we see that:
(f x) y
So the result of (f x) is another function, with as input y. So that means that e ~ b -> f. Thus:
flip :: (c -> (b -> f)) -> (b -> (c -> d))
f :: c -> (b -> f)
x :: b
y :: c
Finally we see that (f y) x is the result of flip f x y. So that means that the type of the result of (f y) x is the same type as d. So that means that f ~ d. Which thus means that:
flip :: (c -> (b -> d)) -> (b -> (c -> d))
Or if we drop some redundant brackets:
flip :: (c -> b -> d) -> b -> c -> d
This is just a matter of solving a system of equations. First, assign unknown types:
f : a1
x : a2
y : a3
Next, f is applied to y. So, f must be a function type with argument of the same type as y, that is
f : a1 = a3 -> a4
f y : a4
Similarily, f y is applied to x, so
f y : a4 = a2 -> a5
f y x : a5
Substituting this back, we get
f : a3 -> a2 -> a5
x : a2
y : a3
We can rename these types
t2 = a3
t1 = a2
t = a5
and get
f : t2 -> t1 -> t
x : t1
y : t2
The function body is f y x, which has type t = a5.

Haskell interpretation of lambda function

i have one Haskell function, which i don't understand but want to.
i :: Int
i = ((\g x -> g x + g x) (\y -> y)) 3
I know what a lambda function is: a nameless function.
E.g. (\x -> x) 3 takes 3 and returns it, (\x y -> x+y) 3 4 takes 3, 4 and returns 7.
But in this special case i can't interpret it. I hope you can help me.
Btw. the solution for this function is 6.
Now your (\y -> y) function is equivalent to id. Let's rewrite your function using that:
i = ((\g x -> g x + g x) id) 3
Now apply the id function to (\g x -> g x + g x). This will get reduced to:
i = (\x -> id x + id x) 3
Now it's simple:
i = id 3 + id 3
i = 6
(\g x -> g x + g x) takes the arguments g, which must be a function, and x, which must be a valid argument to that function, and then adds the result of applying g to x to itself.
In this case \y -> y is supplied as the value for g and 3 as the value for x, so we get (\y -> y) 3 + (\y -> y) 3. (y -> y) 3 is 3, so we get 3 + 3, which is 6.

Confused about functional composition in Haskell

I know that (.) f g x = f (g x). Suppose f has type Int -> Int, g has type Int -> Int -> Int. Now let h be defined by h x y = f (g x y). Which of the following statements are true and why (why not)?
a. h = f . g
b. h x = f . (g x)
c. h x y = (f . g) x y
Supposedly, only b. is true, while the others are false. I would think a. and b. are equivalent... a. is saying two functions are equal. Two functions are equal only iff when I add an argument to the end of both sides, it will still be equal. So I get h x = f . g x. Now (.) is an operator, so functional application takes precedence over it, so f . g x = f . (g x), which is b.
This looks like a homework, so I won't give the answer of which one is correct.
You consider a and b as identical incorrectly. If f . g is applied to x, you get (from the definition of (.))
(f . g) x = f (g x)
But b is f . (g x), which doesn't expand to f (g x). If you follow b through using the definition of (.), you will see the sense in the comments of the others.
Function composition's initial definition is a bit confusing, so I'll write it a different way:
f . g = \a -> f (g a)
This means that f . g returns a function which first applies the argument to g, then applies the result of that to f. This is also clear in the type signature:
(.) :: (b -> c) -> (a -> b) -> (a -> c)
Now for your function h, it has a type of something like h :: a -> a -> a. Remember that -> is right-associative, so the type could be written as h :: a -> (a -> a). Essentially, h :: a -> b, though this type would cause an error because b and a are uninferrable. (.) will only allow one argument to be applied to the first function, so:
-- One could write,
h x y = f (g x y)
-- But One could also write
h x = f . g x
-- Or, more clearly:
h x = (f) . (g x)
This is because Haskell functions are curried, so we can apply some arguments to g without fully evaluating it.
If we imagine what would happen if we applied (.) visually, then simplify, we can see how it works:
h x = \a -> f ((g x) a)
h x = \a -> f (g x a)
h x a = f (g x a)
So yes, b is the answer. This is because (.) only allows one argument to be applied to the first function before moving to the next.
Now you're job can be tackling the other incorrect solutions by simplifying as I have. It's not too difficult.

chaining multi-parameter functions

Suppose I have two functions, f:X->Y and g:Y*Y->Z.
I want to make a third function, h(a, b) = g(f(a), f(b)).
h a b = g (f a) (f b)
Is there any way to write it like h(a, b) = g*f (a, b)?
And what if h(a,b,c,d) = g2*g1*f2*f1 (a,b,c,d), where g_i takes 2 args?
Searching Hoogle for functions with the right signature reveals on from Data.Function. According to its documentation,
g `on` f
seems to be what you want.
The on combinator (in Data.Function, as pointed out by gspr in another answer) is defined by
g `on` f = \x y -> g (f x) (f y)
Which would allow you to write
h = g `on` f
You can make higher-dimensional generalizations of this, for example
g `on3` f = \x y z -> g (f x) (f y) (f z)
g `on4` f = \w x y z -> g (f w) (f x) (f y) (f z)
So that you could write
h = g `on3` f
There may be a way to write on3 and on4 in terms of on, but if there is I can't see it at the moment.
You may also find Arrows interesting. Here's one way to do it:
h g f a b = uncurry g ((f *** f) (a, b))
Which is equivalent to your example (except that g and f are not free) and on. Using:
definition of *** for functions:
(***) f g ~(x,y) = (f x, g y)
definition of uncurry:
uncurry f p = f (fst p) (snd p)
And substituting them into the original equation:
h g f a b = uncurry g (f a, f b) (used *** definition)
h g f a b = g (f a) (f b) (used uncurry definition)