Church numbers at haskell

I am trying to print church numbers in haskell using the definitions:

0 := λfx.x 1 := λfx.fx 

Haskell Code:

 c0 = \fx -> x c1 = \fx -> fx 

When I enter it into the haskell console, I get an error

  test> c1 <interactive>:1:0: No instance for (Show ((t -> t1) -> t -> t1)) arising from a use of `print' at <interactive>:1:0-1 Possible fix: add an instance declaration for (Show ((t -> t1) -> t -> t1)) In a stmt of an interactive GHCi command: print it 

I can’t understand exactly what the error is saying.

Thanks!

+7
source share
2 answers

The problem is that by default it is not possible to print values ​​in Haskell. The default printing method used by the print function and the GHCi REPL, among others, is the show function, defined by a class of type show .

The error you get informs you that you evaluated a type expression that does not have a specific show instance. Modulo some words, this is an error message:

 No instance for (Show ((t -> t1) -> t -> t1)) 

The type ((t -> t1) -> t -> t1) is what was output for the expression you evaluated. This is a valid type for church element 1, although the “correct” type for church numbers should be (a -> a) -> a -> a .

  arising from a use of `print' at <interactive>:1:0-1 

It implicitly uses the print function to display values. This usually tells you where an error was found in your program, but in this case it says <interactive>:1:0-1 , because the error was caused by an expression in REPL.

 Possible fix: add an instance declaration for (Show ((t -> t1) -> t -> t1)) 

It just means that you can fix the error by specifying the expected instance.


Now you probably want to actually print the numbers in your church, and not just know why you cannot. Unfortunately, this is not as simple as adding the requested instance: if you write an instance for (a -> a) -> a -> a , Haskell interprets this as an instance for any specific a , whereas the correct interpretation of the church digit is a polymorphic function that works on any arbitrary a .

In other words, you want your show function to show something like this:

 showChurch n = show $ n (+1) 0 

If you really want this, you can implement the Show instance as follows:

 instance (Show a, Num a) => Show ((a -> a) -> a -> a) where show n = show $ n (+1) 0 

and add {-#LANGUAGE FlexibleInstances#-} to the first line of the file. Or you can implement something like this to convert them to a regular number

 > churchToInt c1 1 > showChurch c1 "1" 

and etc.

+14
source

EDIT: spoiler alert as indicated in the comment

Or, you might have a type for church numbers, something like this:

 data Church x = Church ((x -> x) -> x -> x) zero :: Church x zero = Church (\fx -> x) -- Hack to not clash with the standard succ succ_ :: Church x -> Church x succ_ (Church n) = Church (\fx -> (f (nfx))) instance (Num x) => Show (Church x) where show (Church f) = show $ f (1 +) 0 
+6
source

All Articles