在Haskell中故意定义无限类型 [英] Deliberately defining infinite type in haskell

查看:56
本文介绍了在Haskell中故意定义无限类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想定义似乎需要无限类型的东西.

I want to define what seems to require an infinite type.

必填:函数"eat"吃掉所有参数,但返回"3"的"3"

Required : a function "eat" that eats all it's arguments except "3" for which it returns 3

eat 3 = 3
eat x = eat

因此,基本上,诸如"eat(+)foldl(Just 5)3"之类的任意表达式的求值为3.但是这里的问题是进餐的类型.那应该是什么?

So basically an arbitrary expression like "eat (+) foldl (Just 5) 3" evaluates to 3. But the problem here is the type of eat. What should that be?

我与正在运行的代码最接近的是:

The closest i got to a running code was :

newtype Rec = MakeRec (Int -> Rec)

eat :: Int -> Rec
eat x = MakeRec eat


instance Show Rec where
     show _ = "EAT"

这对吃6"有效,但对吃6 7"无效,如果我在定义中放入(吃3 = 3),则不起作用.

This works okay for "eat 6" but not for "eat 6 7" and it doesn't work if i put (eat 3 = 3) in it's definition.

我不确定在Haskell中是否有可能. (一个参数用来表明它是不可能的?)

I am not sure if this is even possible in Haskell. (What argument would one use to show it's not possible ?)

更新:如以下解决方案所述,在编译时需要类型信息,以便编译器可以知道"eat foldl 3 foldl"是否无效.因此,不可能解决此问题.

UPDATE : As noted in solution below, the type-information is needed at compile time so that compiler can know if "eat foldl 3 foldl" is invalid or not. So, exact solution to this problem is not possible.

推荐答案

这是不可能的.在Haskell中明确禁止了无限类型(不是数据类型),并且很容易生成需要它们的代码,从而产生错误(例如,尝试let foo = (42, foo) in foo).

It's not possible. Infinite types (that aren't data types) are explicitly forbidden in Haskell, and it's easy to produce code which would require them, and thus produces an error (for example, try let foo = (42, foo) in foo).

您当然可以像以前一样使用newtypedata创建它们,但是随后必须显式地将值包装入和拆出构造器.

You can, of course, create them with newtype and data, like you did, but then you have to explicitly wrap and unwrap the values in and out of constructors.

这是一个明确的设计决策:对于无限类型,必须允许许多我们希望编译器拒绝的明显错误的表达式,并且由于将允许更多程序,因此许多以前明确类型的程序将被允许.变得模棱两可, 1 需要显式类型注释.因此需要进行权衡:要求您明确说明无限类型的罕见用法,以换取从类型系统获得更多帮助的回报.

This is an explicit design decision: with infinite types, many obviously wrong expressions that we would like the compiler to reject would have to be allowed, and since many more programs would be allowed, a lot of previously unambiguously-typed programs would become ambiguously typed,1 requiring explicit type annotations. So a tradeoff is made: requiring you to be explicit about the fairly rare uses of infinite types in return for getting much more help from the type system than we otherwise would.

也就是说,有 一种使用类型类定义与eat函数相似的东西的方法,但是只有在给它3时,它才能停止:3是否给定是否为3只能在运行时确定,而类型则在编译时确定.但是,这是一个重载值,可以是Integer,也可以是仅消耗其参数的函数:

That said, there is a way to define something similar to your eat function, using typeclasses, but it can't stop only when you give it a 3: whether you've given it a 3 or not can only be determined at runtime, and types are decided at compile time. However, here's an overloaded value that can be both an Integer, and a function that just eats up its argument:

class Eat a where
    eat :: a

instance Eat Integer where
    eat = 3

instance (Eat r) => Eat (a -> r) where
    eat _ = eat

要注意的是,使用时需要精确地指定类型:

The catch is that you need to specify the types precisely when you use it:

*Main> eat 1 foldr ()

<interactive>:6:1:
    Ambiguous type variable `t0' in the constraint:
      (Eat t0) arising from a use of `eat'
    Probable fix: add a type signature that fixes these type variable(s)
    In the expression: eat 1 foldr ()
    In an equation for `it': it = eat 1 foldr ()
*Main> eat 1 foldr () :: Integer
3

这是因为eat 1 foldr ()可以是Integer,但是它也可以是另一个函数,就像我们在同一表达式中将eat 1eat 1 foldr用作函数一样.同样,我们可以灵活地键入内容,但是必须显式地指定我们想要的类型.

This is because eat 1 foldr () could be an Integer, but it could also be another function, just as we used eat 1 and eat 1 foldr as functions in the same expression. Again, we get flexible typing, but have to explicitly specify the types we want in return.

1 考虑类型类重载,就像重载的数字文字(42可以是Num的任何类型).

1 Think typeclass overloading, like the overloaded numeric literals (42 can be any type that's an instance of Num).

这篇关于在Haskell中故意定义无限类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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