是否有需要使用底部才能具有正确类型的数据结构?



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被视为IntmaxBound

你可能会争辩说,将一个你从不使用的值传递给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

还有一些实现。我知道如果我再搜索一点,我会找到一些东西

最新更新