Haskell类型系统细微差别 [英] Haskell type system nuances

查看:92
本文介绍了Haskell类型系统细微差别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经进入了haskell类型系统的本质,试图获得类型类的精细点。

I've been getting into the nitty gritty of the haskell typesystem and trying to get at the fine points of type classes. I've learned a heap, but I'm hitting a wall on the following pieces of code.

使用这些类和实例定义:

Using these Class and Instance definitions:

class Show a => C a where
  f :: Int -> a

instance C Integer where
  f x = 1

instance C Char where
  f x = if x < 10 then 'c' else 'd'

为什么这样传递类型检查器: p>

Why is it that this passes the type checker:

g :: C a => a -> Int -> a
g x y = f y

yes :: C a => a -> Int -> String
yes x y = show (g x y)

但不是?

g :: C a => a -> Int -> String
g x y = show(f y)

我发现第二个选项更容易阅读,似乎只是一个微小的差别(注意类型签名)。然而,试图让过去的typechecker导致:

I find the second alternative much more readable, and it seems to be only a minor difference (note the type signatures). However, trying to get that past the typechecker results in:

*Main> :l typetests.hs
[1 of 1] Compiling Main             ( typetests.hs, interpreted )

typetests.hs:11:14:
    Ambiguous type variable `a0' in the constraints:
      (C a0) arising from a use of `f' at typetests.hs:11:14
      (Show a0) arising from a use of `show' at typetests.hs:11:9-12
    Probable fix: add a type signature that fixes these type variable(s)
    In the first argument of `show', namely `(f y)'
    In the expression: show (f y)
    In an equation for `g': g x y = show (f y)
Failed, modules loaded: none.

我不明白为什么。

注意:请不要问你想做什么?我希望很明显,我只是在一个抽象的上下文中,为了探索这种语言的工作方式。

Note: Please don't ask "What are you trying to do?" I would hope it is obvious that I'm just messing around in an abstract context in order to probe the way this language works. I have no goal in mind other than learning something new.

感谢

推荐答案

这是一个有趣的玩具发挥的地方。考虑标准的Prelude函数 asTypeOf

This is where a fun toy comes into play. Consider the standard Prelude function asTypeOf.

asTypeOf :: a -> a -> a
asTypeOf = const

它只是返回其第一个参数,是。但是它上面的类型签名放置了两个参数必须是相同类型的附加约束。

It just returns its first argument, no matter what the second argument is. But the type signature on it places the additional constraint that both of its arguments must be the same type.

g :: C a => a -> Int -> String
g x y = show (f y `asTypeOf` x)

现在,GHC知道什么类型的 fy 是。它与 g 的第一个参数的类型相同。没有这些信息,好的,你得到你看到的错误消息。没有足够的信息来确定 f y 的类型。因为类型是重要的(它用于确定要用于 show 的实例),GHC需要知道生成代码的意思是什么类型。

Now, GHC knows what the type of f y is. It's the same as the type of the first argument to g. Without that information, well, you get the error message you saw. There just wasn't sufficient information to determine the type of f y. And because the type is important (it's used to determine which instance to use for show), GHC needs to know what type you mean to generate code.

这篇关于Haskell类型系统细微差别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆