haskell - 从 newtype 转换为 Int 以及从 Int 转换为 newtype

标签 haskell

如何将 newtype 转换为 Int,反之亦然?

我尝试过:

newtype NT1 = NT1 Integer

fromNT1toInt :: NT1 -> Int
fromNT1toInt x = let y = x :: Int
                 in y

但我得到无法匹配预期类型错误

我尝试制作 Enum 类的 NT1 实例 但我不太明白 toEnum 是如何工作的

newtype NT1 = NT1 Integer

instance  Enum NT1 where
toEnum x = let x = x :: Integer
           in if x >= 0
                 then x :: NT1 
                 else x :: NT1

当我调用 toEnum 5::NT1 时,这应该返回 5 NT1 但我收到 StackOverflow 错误。 我哪里出错了?

编辑:新类型名称

最佳答案

e :: t并不意味着“转换表达式 e输入t ”,这只是一个注释,上面写着“e 有类型 t (已经)”。所以这个:

let y = x :: Int in y

含义:断言 x类型为Int ,设置y等于 x ,然后返回y 。这就是类型不匹配的原因:x没有类型 Int正如您向编译器声称的那样。还有这个:

let x = x :: Integer
in if x >= 0 then x :: NT1 else x :: NT1

含义:声明一个新变量x ,将其设置为等于自身(无限循环),断言它的类型为 Integer ,然后测试该无限循环是否返回非负值;无论哪种方式,返回 x ,断言它的类型为 NT1 (这与之前的 Integer 相矛盾)。

Integer之间进行转换和Int ,您可以使用fromIntegral :: (Integral a, Num b) => a -> b ,它将任何整数类型(例如 IntInteger )转换为任何数值类型(例如 IntIntegerFloatDoubleRatio )。

用于从 newtype 进行转换s,您可以使用模式匹配:

fromNT1ToInt :: NT1 -> Int
fromNT1ToInt (NT1 x) = fromIntegral x

或者向 newtype 添加记录访问器函数并使用它:

newtype NT1 = NT1 { nt1Val :: Integer }
-- Note: nt1Val :: NT1 -> Integer

fromNT1ToInt :: NT1 -> Int
fromNT1ToInt nt = fromIntegral (nt1Val nt)
-- Or, with function composition (.):
fromNT1ToInt = fromIntegral . nt1Val

或者,最后,使用coerce来自Data.Coerce :

import Data.Coerce (coerce)

fromNT1ToInt :: NT1 -> Int
fromNT1ToInt nt = fromIntegral (coerce nt :: Integer)

当然,要构造一个 newtype您只需使用它的构造函数 - 在本例中为 NT1 :: Integer -> NT1 ,例如NT1 5 .

关于haskell - 从 newtype 转换为 Int 以及从 Int 转换为 newtype,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53273610/

相关文章:

haskell - 没有 lambda 表达式如何编写这些?

haskell - 如何在 Haskell 中将某些函数应用于文件的每一行

haskell - 我会因为懒惰的评价而养成好/坏的习惯吗?

windows - 如何在Windows中安装haskell openid包

haskell - 进行条件列表理解的惯用方法

performance - Haskell中的平等效率

haskell - 如何使用 Haskell 读取以指数形式写入的整数?

haskell - 数字类型的相等性如何工作?

haskell - 可以复制 thunk 以提高内存性能吗?

haskell - 如果没有明确提及,如何知道模块是否需要 RankNTypes 还是 ExistentialTypes?