为什么不能在一个函数中混合两个原语?

奈尔

我正在按照艰苦的哈斯克尔”方法尝试Haskell,并且一直坚持了解基本类型系统。我有以下代码,而haskell抱怨它无法处理该函数。

f3 :: Num -> Int -> Num
f3 x y = x + y

我认为,它必须与curry或haskell将fxy转换为(fx)y的基本模型有关,但是如果我想将Int传递给Y,我可以这样做吗?如果可以的话我该怎么办?

泽塔

我认为,它必须与curring或haskell将fxy转换为(fx)y的基本模型有关

不。它与类型有关(与在Haskell世界中几乎一样)。首先,Num是一个类型类,而不是一个类型。类型可以是实例一个类型类的,例如IntIntegerDouble是的实例Num现在,让我们看一下加号类型:

(+) :: Num a => a -> a -> a

啊哈!它采用type类型的两个参数a,并返回a,其中a需要是的实例Num(也称为约束)。

现在,我们有足够的信息可以重新访问f3

f3_wrong_sig :: Num -> Int -> Num

经过上面的讨论,很明显f3_wrong_sig签名错误。取而代之的是Num,它需要a受以下约束Num

f3_wrong_implementation :: Num a => a -> Int -> a
f3_wrong_implementation x y = x + y

但是,如果我们还记得的类型(+)x + y则只能用于a并且Int是等效的(也已写成a ~ Int)。我们需要一种从以下方法创建另一个数字类型的方法Int:我们需要一个函数Num a => Int -> a让我们检查有关IntGHCi的一些信息

ghci> :i Int
data Int = GHC.Types.I# GHC.Prim.Int#   -- Defined in `GHC.Types'
-- omitted
instance Integral Int -- Defined in `GHC.Real'
instance Num Int -- Defined in `GHC.Num'
-- omitted

Int不仅是的一个实例Num,而且还是的一个实例Integral快速的搜索为我们提供了fromIntegral :: (Integral b, Num a) => b -> a,我们可以插入它们并最终得到我们想要的东西:

f3 :: Num a => a -> Int -> a
f3 x y = x + fromIntegral y

在这一点上,我们也可以采取最后一步使它变得更加通用,因为它fromIntegral适用于任何情况 Integral

f3_general :: (Integral b, Num a) => a -> b -> a
f3_general x y = x + fromIntegral y

这也是GHC推断的类型。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么我不能在两个渲染函数中传递一个函数?

为什么两个if语句不能在一个函数中起作用?

为什么我不能在一个模板中显示两个列表视图?

为什么不能在另一个函数中定义一个函数?

为什么不能在两个dom元素中追加同一个孩子?

为什么这两个路由器不能在同一个网络中工作?

为什么不能在一行中交换列表中的两个项目?

为什么不能在一个事务中创建和删除表两次?

为什么不能在ruby中对一个实例两次使用相同的方法?

为什么tidyverse :: map不能在一个小标题中同时使用两个列表?

为什么我不能在 Chrome 中声明一个与函数体同名的 let 变量

为什么我不能在Java中声明一个函数数组?

为什么在Java的一个文件中不能定义两个公共类?

当将应用程序部署为JAR时,为什么“ ..”(两个句点)不能在一个目录中工作?

为什么两个jquery函数不能在同一页面上工作?

如果函数是对象,为什么我不能在 JS 中的另一个函数内部调用函数?

java,两个对象,一个不能在方法中解析,另一个可以

为什么我不能在 Javascript 中的同一个类函数中调用一个类函数?

为什么两个跨度不能在div中居中?

为什么我的if语句不能在两个嵌套执行中确定正确的输出?

为什么不能在另一个bean的构造函数中获得SessionScoped bean的值?

为什么不能在一个朋友类中实例化其构造函数是私有的类?

为什么我不能使用两个“if 语句”而不是一个 elif,如果两者中只有一个会执行?

为什么我不能两个接一个地等待?

为什么两个接口不能属于同一个子网?

为什么我不能将两个变量附加为一个元组

为什么我不能按顺序在一个文件中初始化两个静态类变量,而不能初始化三个?

同一个类中的两个函数不能互相访问

为什么函数的交集类型接受两个类型声明中的一个而不同时接受两个类型声明?