Given a function in Agda, some argument, and a new value, how to generate new function where the result for this argument will be the new value - function-definition

Let's suppose that I have some f : A -> B, a : A, b : B. I want new function, that is almost a copy of f, but it should produce b for an argument a.
I was trying something like this.
replace_f : ∀ {A B} (f : A -> B) (a : A) (b : B)
-> (A -> B)
replace_f f a b = \ { a -> b ; attr -> f attr }
But the a in the lambda definition is not the same as a that I am trying to replace.
Agda just considers it as a variable.
P. S.
I have also tried to use Decideable and prop equality in replace_f f a b var = if ⌊ Dec (var ≡ a) ⌋ then b else (f var) .
However, it errors with Set _p_391 !=< Dec _P_386 when checking that the expression Dec (var ≡ a) has type Dec _P_386
P. P. S.
If you want to reproduce the Decidable solution, use these imports
open import Relation.Binary.PropositionalEquality using (_≡_)
open import Relation.Nullary
open import Relation.Nullary.Decidable
open import Relation.Binary.Core
open import Data.Bool

Answer to the question given by my supervisor.
He suggests to implement and provide the equality test for the A type.
Overall, the replace_f will look like this:
replace_f : ∀ {A B} (decide : (x : A) -> (y : A) -> Dec (x ≡ y)) (f : A -> B ) (a : A) (b : B ) -> (A -> B )
replace_f decide f a b var = if ⌊ decide var a ⌋ then b else (f var)
where decide is an actual implementation for comparison
Actually, you could derive Eq clause automatically in Agda, see Haskell Deriving Mechanism for Agda

Related

Unpack Existentials in Existential Type

I tried to write the following code:
{-# LANGUAGE GADTs #-}
module V where
data V a where
V :: (c -> a) -> V a
down :: V (V a) -> V a
down (V f) = V $ \(c,d) -> case f c of
V f' -> f' d
Then GHC answered type variable `c' would escape its scope.
I understand why it doesn't compile: it uses hidden type of existential out of case.
But actually the type is still hidden by V. so essentially function down has no problem I think.
Is there a way to write a compilable down function?
Here's the fundamental problem: f can have a peek at c and use the value of c to determine which type to hide in its existential. For example:
v :: V (V Int)
v = V $ \p -> case p of
False -> V (id :: Int -> Int)
True -> V (fromEnum :: Char -> Int)
So d would need to be both a valid Int and a valid Char if we called down v! To be able to feed an existential that can be so variable, you'll need to ensure that its argument can take on all the types it may demand.
newtype Forall = Forall (forall a. a)
down :: V (V a) -> V a
down (V f) = V $ \(c, d_) -> case f c of
V f' -> case d_ of
Forall d -> f' d
In Haskell, I can't find a simple way to make your code work.
I find it interesting though, that your idea does work in a language with full dependent types like Coq (and likely Agda, Idris, etc.).
The main crux, as Daniel Wagner points out, is that the type resulting from f can depend on the value of c, so the pair (c,d) in the original code should be a dependent pair.
For what it is worth, here's how we can do it in Coq.
Note that this does not involve an uninhabited type like forall a. a.
(* An existential type, under an impredicative encoding *)
Inductive V (A: Type): Type :=
Vk : forall (B: Type), (B -> A) -> V A
.
(* The usual "identity to equivalence" *)
Definition subst {A B: Type} (p: A = B) (x: A): B :=
match p with
| eq_refl => x
end .
(* The main function.
Essentially, we want to turn
Vk B (fun b => Vk C g)
into
Vk (B*C) (fun (b,c) => g c)
but both C and g can depend on (b:B), so (B*C)
should be a Sigma type {b:B & ty b}.
*)
Definition down (A: Type) (x: V (V A)): V A :=
match x with
| Vk B f => let
ty (z: V A): Type := match z with | Vk C g => C end
in Vk A {b:B & ty (f b)} (fun w =>
match w with
| existT b y =>
match f b as o return ty (f b) = ty o-> A with
| Vk C g => fun (h: ty (f b) = C) =>
g (subst h y)
end eq_refl
end )
end .
Thanks for another great answer, chi!
I rewrote the code for Agda and actually it does compile. As an additional note for the above answer, I place my code here.
module down where
open import Level
open import Data.Product
data V {ℓ} (A : Set ℓ) : Set (suc ℓ) where
Vk : {B : Set} → (B → A) → V A
down : ∀ {ℓ} {A : Set ℓ} → V (V A) → V A
down {ℓ} {A} (Vk {B} f) = Vk go where
ty : V A → Set
ty (Vk {C} _) = C
go : Σ B (λ b → ty (f b)) → A
go (b , c) with f b
go (b , c) | Vk {C} g = g c

How to encode the axiom of choice in Haskell/Functional programming?

> {-# LANGUAGE RankNTypes #-}
I was wondering if there was a way to represent the axiom of choice in haskell and/or some other functional programming language.
As we know, false is represented by the type with no values (Void in haskell).
> import Data.Void
We can represent negation like so
> type Not a = a -> Void
We can express the law of excluded middle for a type a like so
> type LEM a = Either a (Not a)
This means we can make classical logic into a Reader monad
> type Classical a = (forall r. LEM r) -> a
We can, for example, do double negation elimination in it
> doubleneg :: Classical (Not (Not a) -> a)
> doubleneg = \lem nna -> either id (absurd . nna) lem
We can also have a monad where the law of excluded middle fails
> type AntiClassical a = Not (forall r. LEM r) -> a
Now the question is, how can we make a type that represents the axiom of choice? The axiom of choice talks about sets of sets. This implies we would need types of types or something. Is there something equivalent to the axiom of choice that could be encoded? (If you can encode the negation, just combine it with the law of excluded middle). Maybe trickery would allow us to have types of types.
Note: Ideally, it should be a version of the axiom of choice that works with Diaconescu's theorem.
This is just a hint.
The axiom of choice can be expressed as:
If for every x : A there's a y : B such that the property P x y holds, then there's a choice function f : A -> B such that, for all x : A we have P x (f x).
More precisely
choice : {A B : Set} (P : A -> B -> Set) ->
((x : A) -> Σ B (λ y -> P x y)) ->
Σ (A -> B) (λ f -> (x : A) -> P x (f x))
choice P h = ?
given
data Σ (A : Set) (P : A -> Set) : Set where
_,_ : (x : A) -> P x -> Σ A P
Above, choice is indeed provable. Indeed, h assigns to each x a (dependent) pair whose first component y is an element of A and the second component is a proof that the first indeed satisfies P x y. Instead, the f in the thesis must assign to x only y, without any proof.
As you see, obtaining the choice function f from h is just a matter of discarding the proof component in the pair.
There's no need to extend Agda with LEM or any other axiom to prove this. The above proof is entirely constructive.
If we were using Coq, note that Coq forbids to eliminate a proof (such as h : ... -> Prop) to construct a non-proof (f), so translating this into Coq directly fails. (This is to allow program extraction.) However, if we avoid the Prop sort of Coq and use Type directly, then the above can be translated.
You may want to use the following projections for this exercise:
pr1 : ∀ {A : Set} {P} -> Σ A P -> A
pr1 (x , _) = x
pr2 : ∀ {A : Set} {P} -> (p : Σ A P) -> P (pr1 p)
pr2 (_ , y) = y

Why won't this simple Morte program typecheck?

I'm trying to better understand the Calculus of Constructions through Morte. My first attempt was to call the identity function itself. However,
(
λ (idType : *) →
λ (id : idType) →
(id idType))
(∀(t : *) → ∀(x : t) → t)
(λ(a : *) → λ(x : a) → x)
That program fails to compile with the error:
Context:
idType : *
id : idType
Expression: id idType
Error: Only functions may be applied to values
That doesn't make sense to me, since id is the function (λ(a : *) → λ(x : a) → x), of type idType == (∀(t : *) → t → t). Why I'm getting this error?
Your
T = (λ (idType : *) →
λ (id : idType) →
(id idType))
is ill-typed. Otherwise T nat 4 would also type check (pretending we have naturals to help intuition).
If you want to write an application function (like Haskell's $) you can use
apply =
(λ (a b : *) →
λ (f : a -> b) →
λ (x : a) →
f x)
Note that the above only applies to non-dependent fs. In the dependent case, b can depend on the actual value of type a, making things quite more complex, since now b is a function.
applyDep =
(λ (a : *) →
λ (b : a -> *) →
λ (f : ∀(x : a) -> b x) →
λ (x : a) →
f x)
An example (simplified syntax):
applyDep
Bool
(λ (x : Bool) -> if x then Int else Char)
(λ (x : Bool) -> if x then 4 else 'd')
True
Above I am quite sloppy on the dependent function (the last lambda), since the if is ill-typed (different types for the branches), but you might get the rough idea. To write it more precisely, I would need something like the dependent match/case Coq has (or to rely to a dependent eliminator for Bool):
fun x: Bool =>
match x as y return (if y then Int else Char) with
| True => 3
| False => 'a'
end
In the above "if", I had to make it clear that the type of the two branches is different (Int vs Char), yet it can be typed if we take that as the result of g x, where g = fun y => if y then Int else Char. Basically, the result type is now dependent the x value.
The problem here is that with Church-style typing (here is a nice blogpost and some discussion) everything must be well-typed from the beginning: if you have a well-typed f and a well-typed x, then you can apply f to x (if types match). If f is not well-typed, then it's not a legal term and you have an error, even if it is possible to assign f x a type.
Your λ (idType : *) → λ (id : idType) → (id idType) is not well-typed: id is a term of type idType and it's not a function that receives *, so you can't apply it to idType.

Understanding the signature of <$>

I have the applicative <$> operator more or less figured out, but I can't understand the signature I'm getting with the following example:
ghci> let f x y z = x + y + z -- f::Num a => a -> a -> a -> a
ghci> f <$> Just 2 <*> Just 3 <*> Just 4
Just 9
This result I understand, but when checking the following type:
ghci> :t (<$> f)
(<$> f) :: Num a => ((a -> a -> a) -> b) -> a -> b --This makes no sense to me
That signature I would understand as : a function that takes a (a -> a- > a) -> b function and an a as parameters and returns a b. According to this reasoning , I should call this like :
(<$>f) f 4
which would result in an Integer.
Obviously this is not true, so can you please help me understand how to read the type of (<$> f)?
a function that takes a (a -> a- > a) -> b function and an a as parameters and returns a b.
This is correct.
According to this reasoning , I should call this like :
(<$>f) f 4
which would result in an Integer.
No, because f does not have type (a -> a -> a) -> b or one compatible with it. Instead it has type Num a => a -> a -> a -> a. That is, f takes three numbers and produces a number, whereas we're looking for a function that takes a function (of type a -> a -> a) as its first argument.
<$> takes as a second argument something of type g b, where g is any applicative functor.
You are passing f :: Num a => a -> a -> a -> a as a second argument. Let's ignore the Num a context to keep things simple.
Hence, we look for g,b such that g b = a -> a -> a -> a.
Let's write the type of f in prefix form:
f :: (->) a ((->) a ((->) a a)) = g b
Hence, g = (->) a and b = ((->) a ((->) a a)). The latter is b = a -> a -> a in infix form.
It happens that (->) a is an applicative functor, so <$> f type checks. Note however that <$> is used on a completely different functor than the Maybe one you were using in your examples. Hence the confusion.
TL;DR: overloaded identifiers can shapeshift to many things adapting to their contexts, possibly in some unexpected way.

Encoding the dynamicaly-typed lambda calculus in Haskell using recursive types

I'm reading Pierce's Types and Programming Languages book and in the chapter about recursive types he mentions that they can be used to encode the dynamic lambda calculus in a typed language. As an exercise, I'm trying to write that encoding in Haskell but I can't get it to pass the typechecker:
{-# LANGUAGE RankNTypes, ScopedTypeVariables #-}
data D = D (forall x . x -> x )
lam :: (D -> D) -> D
--lam f = D f
lam = undefined
ap :: D -> D -> D
ap (D f) x = f x
--Some examples:
myConst :: D
myConst = lam (\x -> lam (\y -> x))
flippedAp :: D
flippedAp = lam (\x -> lam (\f -> ap f x))
Right now, this code gives me the following error message (that I don't really understand):
dyn.hs:6:11:
Couldn't match type `x' with `D'
`x' is a rigid type variable bound by
a type expected by the context: x -> x at dyn.hs:6:9
Expected type: x -> x
Actual type: D -> D
In the first argument of `D', namely `f'
In the expression: D f
In an equation for `lam': lam f = D f
Changing the definition of lam to undefined (the commented-out line) gets the code to compile so I suspect that whatever I did wrong is either on lam's definition or in the original definition for the D datatype.
The reason this doesn't work is because f :: D -> D. D wants a function which can take in any type x and return x. This is equivalent to
d :: forall a. a -> a
As you can see, the only sane implementation for this is id. Try
data D = D (D -> D)
...
unit = D id
Perhaps for better printing:
data D = DFunc (D -> D) | DNumber Int
The issue is that your f has type D -> D (according to your type signature for lam), but the D constructor expects an argument of type forall x . x -> x. Those are not the same type, so the compiler complains

Resources