Question

Imagine I have a function with a domain of all integers bigger than 0. I want the result of other inputs to be undefined. For the sake of simplicity, let's say this is the increment function. In Haskell, I could achieve this with something like

f :: Integer -> Integer
f x 
  | x > 0 = x + 1
  | otherwise = undefined

Of course, the example is quite gimped but it should be clear what I want to achieve. I'm not sure how to achieve the similar in Scheme.

(define (f x)
  (if (> x 0)
      (+ x 1)
      (?????)))

My idea is to just stick an error in there but is there any way to replicate the Haskell behaviour more closely?

Was it helpful?

Solution

Your question is related to this one which has answers pointing out that in R5RS (which I guess MIT scheme partially supports?), the if with one branch returns an "unspecified value". So the equivalent to the haskell code should be:

(define (f x)
  (if (> x 0)
      (+ x 1)))

You probably already know this: in haskell undefined is defined in terms of error, and is primarily used in development as a placeholder to be removed later. The proper way to define your haskell function would be to give it a type like: Integer -> Maybe Integer.

OTHER TIPS

A common undefined value is void defined as (define void (if #f #f)).

Notice that not all Scheme implementations allow an if without the alternative part (as suggested in the other answers) - for instance, Racket will flag this situation as an error.

In Racket you can explicitly write (void) to specify that a procedure returns no useful result (check if this is available in MIT Scheme). From the documentation:

The constant #<void> is returned by most forms and procedures that have a side-effect and no useful result. The constant #<undefined> is used as the initial value for letrec bindings. The #<void> value is always eq? to itself, and the #<undefined> value is also eq? to itself.

(void v ...) → void? Returns the constant #<void>. Each v argument is ignored.

That is, the example in the question would look like this:

(define (f x)
  (if (> x 0)
      (+ x 1)
      (void)))

Speaking specifically to MIT Scheme, I believe #!unspecific is the constant that is returned from an if without an alternative.

(eq? (if (= 1 2) 3) #!unspecific) => #t
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top