'How do you write a declaration in racket that returns either a string or #f (false)?

I have the following function in racket:

( : search-stack : Symbol KeyStack -> String) (define (search-stack s stack)

This function searches the stack for a specific string and returns the matching symbol. If the string is not found, the function returns "#f". How do I modify the return type to allow for returning either a string or boolean type (false only)?



Solution 1:[1]

Consider the simpler function match, which just checks a pair (which could be one element of a stack). With signature (informal type as a comment) this could be:

#lang racket

(define (match s p) ;; Symbol (Symbol . String) -> "String or #f"
  ;; produce string if s matches, otherwise #f
  (if (eq? s (car p))
      (cdr p)
      #f))

In typed-racket, with type annotations on the arguments, this is:

#lang typed/racket

(define (match [s : Symbol] [p : (Pairof Symbol String)])
  (if (eq? s (car p))
      (cdr p)
      #f))

Now just type match into the DrRacket interactions area, and type induction will reveal the return type:

Welcome to DrRacket, version 8.4 [cs].
Language: typed/racket, with debugging.
> match
- : (-> Symbol (Pairof Symbol String) (U False String))
#<procedure:match>
> 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mnemenaut