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?

Était-ce utile?

La 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.

Autres conseils

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top