Skip to content

Instantly share code, notes, and snippets.

@mbbx6spp
Created September 5, 2017 19:19
Show Gist options
  • Select an option

  • Save mbbx6spp/336ec9e850e410530dd9b810d433fb23 to your computer and use it in GitHub Desktop.

Select an option

Save mbbx6spp/336ec9e850e410530dd9b810d433fb23 to your computer and use it in GitHub Desktop.
Exercise about definition of combinator.
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE RankNTypes #-}
module FooBarBaz.Main
( compose3a
, compose3b
, compose3c
, main
) where
{-
RULES:
1. Do not import any more packages or names into scope
2. Ensure your module type checks and follow the suggestions above each definition
3. Add non-code answers as comments with an `-- ANSWER` prefix.
-}
import Prelude (IO, String, error, print, ($), (*), (+), (++), (.),
(==), (^))
{-
EXERCISE:
Ok, for today, here is a brief exercise that I started working on for the
lambda calculus part was this:
Suppose `\x. E` is a lambda (function) that has one bound variable `x` in an
expression `E` (`E` could be any expression but example might look like `x`,
`x y`, `x x`, or another lambda). The part of the lambda that is to the LHS
of the `.` is the head and the RHS is the body. In Haskell, this can be
represented as an anonymous function like so: `\x -> e` where `e` is the
Haskell representation of the expression, `E`.
*Definition:* a lambda is said to be a _combinator_ if it does not contain
any unbound variables in the expression `E`, i.e. expression `E` only
contains references to the variables given in the head of the lambda, except
those that are fully defined inside the expression, `E`.
Define a body in Haskell syntax for a lambda that has the following type:
```
forall a b c d.
(a -> b)
-> (b -> c)
-> (c -> d)
-> a
-> d
```
Use the guided directions in comments below.
-}
todo :: forall a. String -> a
todo msg = error ("TODO: define " ++ msg)
compose3a, compose3b, compose3c ::
forall a b c d.
(a -> b)
-> (b -> c)
-> (c -> d)
-> a
-> d
-- TODO: Replace RHS of this definition based on suggestion below:
-- Use ($) in this definition. Is this definition a combinator given the definition above? If not, why?
-- ANSWER:
compose3a f g h a = todo "compose3a"
-- TODO: Replace RHS of this definition based on suggestion below:
-- Use (.) in this definition. Is this definition a combinator given the definition above? If not, why?
-- ANSWER:
compose3b f g h = todo "compose3b"
-- TODO: Replace RHS of this definition based on suggestion below:
-- Use only parentheses and bound variables in this definition. Is this a combinator? If not, why?
-- ANSWER:
compose3c f g h a = todo "compose3c"
main :: IO ()
main = do
print $ compose3a (+1) (^2) (*2) 5 == 72
print $ compose3b (+1) (*2) (^2) 5 == 144
print $ compose3c (*2) (^2) (+1) 5 == 101
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment