1

I am working on a larger project translating Haskell to Lambda calculus. I would like to give a lambda term to specific Haskell functions. I am not quite sure how to approach two of them. I went ahead and created the property each term should have, just to give you an idea of what I am trying to do.

What would the $\lambda$-terms for these Haskell functions be? If you could give a brief explanation that would be super helpful.

Function 1: $\mathsf{foldr}$: It should have the property

$$\mathsf{foldr} \, f \, u \, [N_1, \dots ,N_k] \to_\beta^* f N_1 (f N_2 (\dots (f N_k u)))$$

Function 2: $\mathsf{map}$: It should have the property

$$\mathsf{map} \, f \, [N_1, \dots,N_k] \to_\beta^* [f N_1,f N_2, \dots,f N_k]$$

GEU197
  • 11
  • Do you know how to encode a list of terms into a lambda-term? – Taroccoesbrocco Dec 25 '20 at 10:23
  • Yes, [N1,N2,...,Nk] = λc.λn.c N1 (c N2 (...(c Nk n)...)). It still doesnt help me though... I am really confused about writing lambda terms for the folders. – GEU197 Dec 25 '20 at 10:24

1 Answers1

1

Given that a list $[N_1, \dots, N_k]$ of $\lambda$-terms is represented by the $\lambda$-term $$\lambda c. \lambda n. c N_1 (c N_2( \dots(c N_k n) \dots ))$$ it is easy to define the $\lambda$-terms $\mathsf{foldr}$ and $\mathsf{map}$.

  1. $\mathsf{foldr} \, f \, u \, [N_1, \dots, N_k] \to_\beta^* f N_1 (f N_2( \dots (f N_k u) \dots ))$. Here, the intuition is to bring $\lambda c. \lambda n. c N_1 (c N_2( \dots(c N_k n) \dots ))$ (i.e. the list $[N_1, \dots, N_k]$) in "head position" and apply it to $f$ and then to $u$, so that, when the $\beta$-steps destroy $\lambda c$ and $\lambda n$, $f$ substitutes for $c$, and $u$ substitutes for $n$. Which $\lambda$-term $\mathsf{foldr}$ allows us to do that?

! Let $\mathsf{foldr} = \lambda f'. \lambda u'. \lambda l. lf'u'$. Then, \begin{align} \mathsf{foldr} \, f \, u \, [N_1, \dots, N_k] &= (\lambda f'. \lambda u'. \lambda l. lf'u') f \, u \, [N_1, \dots, N_k] \\ &\to_\beta (\lambda u'. \lambda l. l f u') \, u \, [N_1, \dots, N_k] \\ &\to_\beta (\lambda l. l f u) [N_1, \dots, N_k] \\ &\to_\beta [N_1, \dots, N_k] \, f \, u \\ &= \big( \lambda c. \lambda n. c N_1 (c N_2( \dots(c N_k n) \dots )) \big) f u \\ &\to_\beta \big( \lambda n. f N_1 (f N_2( \dots(f N_k n) \dots )) \big) u \\ &\to_\beta f N_1 (f N_2( \dots(f N_k u) \dots )) \end{align}

  1. $\mathsf{map} \, f \, [N_1, \dots, N_k] \to_\beta^* [f N_1, \dots, f N_k]$. Here the idea is a variant of the previous point: bring $\lambda c. \lambda n. c N_1 (c N_2( \dots(c N_k n) \dots ))$ (i.e. the list $[N_1, \dots, N_k]$) in "head position" and then replace each $N_i$ with $f N_i$, so as to obtain $\lambda c. \lambda n. c (fN_1) (c (fN_2) ( \dots(c (f N_k) n) \dots ))$, i.e. the list $[f N_1, \dots, f N_k]$. How can each $N_i$ be replaced by $f N_i$? The $\lambda$-term $\lambda c. \lambda n. c N_1 (c N_2( \dots(c N_k n) \dots ))$ (i.e. the list $[N_1, \dots, N_k]$) should be applied to the $\lambda$-term $\lambda x . c (fx)$, so that, when the $\beta$-step destroys $\lambda c$ in the list, $\lambda x. c (f x)$ substitutes for $c$ and then $(\lambda x. c (f x))N_i \to_\beta c (f N_i)$. Summing up, which $\lambda$-term $\mathsf{map}$ allows us to do all that?

! Let $\mathsf{map} = \lambda f'. \lambda l. \lambda c. l \, \lambda x. c (f'x)$. Then, \begin{align} \mathsf{map} \, f \, [N_1, \dots, N_k] &= \big( \lambda f'. \lambda l. \lambda c. l \, \lambda x. c (f'x) \big) f \, [N_1, \dots, N_k] \\ &\to_\beta \big( \lambda l. \lambda c. l \, \lambda x. c (f x) \big) [N_1, \dots, N_k] \\ &\to_\beta \lambda c. [N_1, \dots, N_k] \lambda x. c (f x) \\ &= \lambda c. \big( \lambda c'. \lambda n. c' N_1 (c' N_2( \dots(c' N_k n) \dots )) \big) \lambda x.c (f x) \\ &\to_\beta \lambda c. \lambda n. (\lambda x.c (f x)) N_1 ((\lambda x.c (f x)) N_2( \dots( (\lambda x.c (f x)) N_k n) \dots )) \\ &\to_\beta \lambda c. \lambda n. c (f N_1) ((\lambda x.c (f x)) N_2( \dots( (\lambda x.c (f x)) N_k n) \dots )) \\ &\to_\beta \lambda c. \lambda n. c (f N_1) (c (f N_2) ( \dots( (\lambda x.c (f x)) N_k n) \dots )) \\ &\to_\beta^* \lambda c. \lambda n. c (f N_1) (c (f N_2) ( \dots( c (f N_k) n) \dots )) \\ &= [f N_1, \dots, f N_k] \end{align}

  • That is indeed very good Answer. Expanding a bit on the topic. Could the two terms and infinite list be typed as well? As in typed lambda calculus ? – gaming4 mining Jul 05 '21 at 11:00
  • 1
    @gaming4mining - Yes and yes. For infinite lists (in the untyped case, but the typed case is analogous) see also this question and its accepted answer. If you are looking for more specific information, it could be worthy to post a new question. – Taroccoesbrocco Jul 05 '21 at 14:25
  • @gaming4mining - As a general rule in this site, please if you find an interesting question and/or answer, don't hesitate to upvote them: rewarding is the best spur to high quality questions and answers. – Taroccoesbrocco Jul 05 '21 at 14:29
  • yes you are right. Is there any specific rule or general consensus why they can be typed? Since here: https://math.stackexchange.com/questions/3965504/lambda-calculus-beta-reductions?rq=1 it it sounds like it can't be actually typed. I'm trying to understand what is the logic for expressions to be "Typeable" – gaming4 mining Jul 05 '21 at 15:05
  • 1
    @gaming4mining - Do you know what a fixpoint combinator is? How it can be represented in the $\lambda$-calculus? The usual representation of a fixpoint combinator cannot be typed (at least with simple types), but you can enrich the $\lambda$-calculus with a special constant representing a fixpoint compinator, and this constant can be typed. Your question deserves a separate post for a decent answer. – Taroccoesbrocco Jul 05 '21 at 15:21
  • Thank you for the answer. I've created a question specifically about these cases link – gaming4 mining Jul 07 '21 at 11:03