Clone

Posted on 2018-02-18 by nbloomf
Tags: arithmetic-made-difficult, literate-haskell

This page is part of a series on Arithmetic Made Difficult.

This post is literate Haskell; you can load the source into GHCi and play along.


{-# LANGUAGE NoImplicitPrelude #-}
module Clone (
  clone, _test_clone, main_clone
) where

import Testing
import Functions
import Flip

Today we’ll define some operators for repeating function arguments. These will be handy for defining functions that need to “consume” their input more than once.

Let \(A\) and \(B\) be sets. We define \[\clone : (A \rightarrow A \rightarrow B) \rightarrow A \rightarrow B\] by \[\clone(f)(x) = f(x)(x).\]

In Haskell:

\(\clone\) interacts with \(\flip\).

Let \(A\) and \(B\) be sets, with \(f : A \rightarrow A \rightarrow B\). Then we have \[\clone(\flip(f)) = \clone(f).\]

Let \(x \in A\). Then we have \[\begin{eqnarray*} & & \clone(\flip(f))(x) \\ & \href{/posts/arithmetic-made-difficult/Clone.html#def-clone} = & \flip(f)(x)(x) \\ & \href{/posts/arithmetic-made-difficult/Flip.html#def-flip} = & f(x)(x) \\ & \href{/posts/arithmetic-made-difficult/Clone.html#def-clone} = & \clone(f)(x) \end{eqnarray*}\] as claimed.

\(\clone\) is a left inverse of \(\const\).

Let \(A\) be a set. For all \(x \in A\) we have \[\clone(\const)(x) = x.\]

We have \[\begin{eqnarray*} & & \clone(\const)(x) \\ & \href{/posts/arithmetic-made-difficult/Clone.html#def-clone} = & \const(x)(x) \\ & \href{/posts/arithmetic-made-difficult/Functions.html#def-const} = & x \end{eqnarray*}\]

The same, but moreso.

Let \(A\) and \(B\) be sets. We define \[\cloneC : (A \rightarrow A \rightarrow A \rightarrow B) \rightarrow A \rightarrow B\] by \[\cloneC = \compose(\clone)(\compose(\clone)).\]

In Haskell:

\(\cloneC\) does what we expect:

Let \(A\) and \(B\) be sets. For all \(f : A \rightarrow A \rightarrow A \rightarrow B\) and all \(x \in A\), we have \[\cloneC(f)(x) = f(x)(x)(x).\]

We have \[\begin{eqnarray*} & & \cloneC(f)(x) \\ & \href{/posts/arithmetic-made-difficult/Clone.html#def-clone3} = & \compose(\clone)(\compose(\clone))(f)(x) \\ & \href{/posts/arithmetic-made-difficult/Functions.html#def-compose} = & \clone(\compose(\clone)(f))(x) \\ & \href{/posts/arithmetic-made-difficult/Clone.html#def-clone} = & \compose(\clone)(f)(x)(x) \\ & \href{/posts/arithmetic-made-difficult/Functions.html#def-compose} = & \clone(f(x))(x) \\ & \href{/posts/arithmetic-made-difficult/Clone.html#def-clone} = & f(x)(x)(x) \end{eqnarray*}\] as claimed.

Testing

Suite:

_test_clone ::
  ( Equal a, Show a, Arbitrary a, CoArbitrary a
  , Equal b, Show b, Arbitrary b, CoArbitrary b
  ) => Int -> Int -> a -> b -> IO ()
_test_clone size cases a b = do
  testLabel0 "clone"
  let args = testArgs size cases

  runTest args (_test_clone_flip a b)
  runTest args (_test_clone_const a)
  runTest args (_test_clone3 a b)

Main:

main_clone :: IO ()
main_clone = do
  _test_clone 1 1 () ()