gpt4 book ai didi

Haskell:具有逻辑上不同 bool 值的类型安全

转载 作者:行者123 更新时间:2023-12-04 09:04:24 25 4
gpt4 key购买 nike

假设我有以下代码

type IsTall = Bool
type IsAlive = Bool

is_short_alive_person is_tall is_alive = (not is_tall) && is_alive

说,稍后,我有以下
a :: IsAlive
a = False

b :: IsTall
b = True

并调用以下命令,以错误的方式获取两个参数:
is_short_alive_person a b

不幸的是,这成功编译,并且在运行时找到了高个子死人而不是短命人。

我希望上面的示例不要编译。

我的第一次尝试是:
newtype IsAlive = IsAlive Bool
newtype IsTall = IsTall Bool

但是我不能做类似的事情。
switch_height :: IsTall -> IsTall
switch_height h = not h

not未在 IsTall 上定义s,仅 Bool s。

我可以显式提取 Bool s 所有的时间,但这在很大程度上违背了目的。

基本上,我想要 IsTall s 与其他人互动 IsTall s,就像他们是 Bool s,除非它们不会与 Bool 交互s 和 IsAlive s 没有明确的类型转换。

实现这一目标的最佳方法是什么。

p.s.我想我已经通过在 GHC 中的数字实现了这一点:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype UserID = UserID Int deriving (Eq, Ord, Num)
newtype GroupID = GroupID Int deriving (Eq, Ord, Num)

(即 UserID 和 GroupID 不应该交互)

但我似乎无法使用 Bool 执行此操作s(派生 Bool 不起作用)。我什至不确定以上是最好的方法。

最佳答案

如果你稍微改变你的数据类型,你可以让它成为 Functor 的一个实例,然后你可以使用 fmap 对 bool 值进行操作

import Control.Applicative

newtype IsAliveBase a = IsAlive a
newtype IsTallBase a = IsTall a

type IsAlive = IsAliveBase Bool
type IsTall = IsTallBase Bool

instance Functor IsAliveBase where
fmap f (IsAlive b) = IsAlive (f b)

instance Functor IsTallBase where
fmap f (IsTall b) = IsTall (f b)

switch_height :: IsTall -> IsTall
switch_height h = not <$> h -- or fmap not h

- 编辑

对于 && 之类的操作,您可以将其设为 Applicative 的实例
instance Applicative IsAliveBase where
pure = IsAlive
(IsAlive f) <*> (IsAlive x) = IsAlive (f x)

然后你可以使用 liftA2 做 (&&)

例子:
*Main> let h = IsAlive True
*Main> liftA2 (&&) h h
IsAlive True

您可以在 http://en.wikibooks.org/wiki/Haskell/Applicative_Functors 阅读更多相关信息

关于Haskell:具有逻辑上不同 bool 值的类型安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10544984/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com