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

时间:2018-11-13 04:03:35

标签: haskell

如何将新类型转换为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错误。 我在哪里犯错?

已编辑:新类型名称

2 个答案:

答案 0 :(得分:6)

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相矛盾)。

要在IntegerInt之间进行转换,可以使用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 -> NT1NT1 5

答案 1 :(得分:4)

使用<ul> <li (mouseover)="changeStyle()" (mouseout)="changeStyle()" [className]="hovered ? 'hover-open nav-item':'nav-item'"><a href="#">Link 1</a></li> <li (mouseover)="changeStyle()" (mouseout)="changeStyle()" [className]="hovered ? 'hover-open nav-item':'nav-item'"><a href="#">Link 2</a></li> <li (mouseover)="changeStyle()" (mouseout)="changeStyle()" [className]="hovered ? 'hover-open nav-item':'nav-item'"><a href="#">Link 3</a></li> <li (mouseover)="changeStyle()" (mouseout)="changeStyle()" [className]="hovered ? 'hover-open nav-item':'nav-item'"><a href="#">Link 4</a></li> </ul> 在整数类型之间进行转换,例如import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-menu-bar', templateUrl: './menu-bar.component.html' }) export class MenuBarComponent implements OnInit { constructor() { } ngOnInit() { } hovered = false; changeStyle($event) { this.hovered = !this.hovered; } } fromIntegral。使用IntInteger转换为NT1,并从IntegerNT1进行模式匹配。最后,您可以编写函数来连接事物。

NT1