Haskell中是否有一种类型绝对需要使用底部值,即undefined
?或者它只是用于在代码进行时获取代码编译?
我认为可能存在一种需要undefined
才能完成构造的稀有类型,列表只需要1:[]
,仅此而已,但也许数据类型足够复杂,需要未定义才能完成其构造。
是否有更复杂的构造函数需要undefined
键入?
有时,您希望传递一个值只是为了传递该值的类型,而您并不关心实际值。以asTypeOf :: a -> a -> a
为例。它不检查是秒参数,它只是在那里设置类型a
:
Prelude> maxBound `asTypeOf` (0::Word)
18446744073709551615
Prelude> maxBound `asTypeOf` (0::Int)
9223372036854775807
Prelude> maxBound `asTypeOf` (undefined::Int)
9223372036854775807
如您所见,asTypeOf
可以完美地将undefined
作为其第二个参数的值传递,因为任何Int
类型的值都会导致maxBound
被视为Int
的maxBound
。
你可能会争辩说,将一个你从不使用的值传递给asTypeOf
是一个愚蠢的想法。这种类型感觉不对。相反,您只需要传递携带类型信息的内容。有使用该想法的Proxy
类型的实现,尽管Proxy
的标准版本略有不同。一个简单的Proxy
实现可以像这样工作:
-- Note: No data constructor at all.
-- This type is uninhabitated, the only possible value is undefined
data Proxy a
-- generator function for a proxy value. As there is no value, it has to return
-- undefined.
proxy :: Proxy a
proxy = undefined
asProxiedBy :: a -> Proxy a -> a
asProxiedBy x _ = x
使用此代码,您可以编写
*Main> maxBound `asProxiedBy` (proxy :: Proxy Int)
9223372036854775807
在此修订的示例中,将asTypeOf
替换为asProxiedBy
,不再传递未使用的值,而是将未定义的值作为引用类型传递。为了避免拼写丑陋的单词undefined
,引入了proxy
方法来生成所有Proxy
类型的undefined
值。
最后,我找到了一些未定义可以适合的示例:
newtype Wrap = W {w :: Wrap} deriving Show
www = W $ W $ W $ undefined
你可以数它们(没有尽头(:
count :: Wrap -> Int
count (W a) = count a + 1
在这里,Wrap
需要undefined
结束。
class Peano a where
zero :: a
next :: a -> a
alt_zero, alt_one, alt_two, alt_three :: (Peano a) => a
alt_zero = undefined
alt_one = next alt_zero -- = succ undefined
alt_two = next alt_one -- = succ (succ undefined)
alt_three = next alt_two -- = succ (succ (succ undefined))
在这里,您可以创建没有实例的 1、2、3,或者您也可以给出具体类型。
data Nat = Z | S Nat deriving Show
instance (Peano Nat) where
zero = Z
next = S
instance (Peano Wrap) where
zero = undefined
next = W
countN :: Nat -> Int
countN Z = 0
countN (S n) = (countN n) + 1
还有一些实现。我知道如果我再搜索一点,我会找到一些东西