当参数的类型为联合类型时,确定 Racket 中参数的特定类型



为混乱的标题道歉——我的技术词汇缺乏,我不确定如何表达这一点。我如何在不知道的情况下将 Racket 中的参数识别为某种类型

  • 类型的构造函数(用于match)
  • 一个函数type?(例如integer?)检查它是否是指定的类型?

具体来说,假设我有一些类型(: fn : (All (a b c) (a -> c) (b -> c) (Listof (U a b)) -> Listof c))的函数;我们可以想象它被称为(fn fa fb xs)。我希望这个函数将xs转换为Listof c;它应该通过将xs的每个元素x映射到(fa x)如果x类型为a,并且(fb x)如果x类型为b类型。例如,我们可以获取字符串和实数的列表,并将字符串映射到它们的长度,并将实数映射到最接近的整数。

在我知道aString并且bReal的特定情况下,我可以写类似的东西

(define (fn fa fb xs)
(map (lambda (x) (if (string? x) (fa x) (fb x))) xs))

但这只有在我有一个已知的函数string?来检查x类型时才有效。

是否有可能按照我在球拍中的建议进行操作?

Typed Racket中没有"类型"操作,所以答案是否定的。但是,您可以将"决策程序"传递给fn以选择应使用哪个函数来应用于每个元素。

->窗体允许您指定出现类型命题,因此您可以编写以下代码:

#lang typed/racket
(: fn (All (a b c)
((U a b) -> Boolean : a)
(a -> c)
(b -> c)
(Listof (U a b))
->
(Listof c)))
(define (fn decider fa fb xs)
(map (lambda ([x : (U a b)])
(if (decider x) (fa x) (fb x)))
xs))

然后你可以调用它:

(fn string? string-length add1 (list 1 "a" 23 "bc"))
;; '(2 1 24 2)

感谢Sam Tobin-Hochstadt的帮助!

最新更新