为什么Haskell不允许所有类型的函数定义? [英] Why is function definition for all types at once not allowed in Haskell?

查看:130
本文介绍了为什么Haskell不允许所有类型的函数定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能是一个非常基本的问题,但是...

定义为一个函数,比如说

  foo :: a  - >整数

表示从任何类型到一个Integer的函数。如果是这样的话,那么理论上应该可以将它定义为任何类型,例如

  foo 1 = 10 
foo 5.3 = 100
foo(x:xs)= -1
foo _ = 0

但Haskell只允许一个通用的定义,如 foo a = 0

即使您将 a 限制为某一类的类型之一,例如显示类别类别:

  foo ::(显示a)=> a  - >整数

您仍然无法做类似的事情

  foohello= 10 
foo _ = 0

即使hello:: [Char] Show

的实例

为什么会有这种限制?

解决方案

这是一项功能,实际上非常基本。它归结为编程语言理论中称为 parametricity 的属性。粗略地说,这意味着评估不应该依赖编译时变量的类型。你不能在静态不知道具体类型的地方查看一个值。



为什么这么好?它给了程序更强大的不变性。例如,从单独的类型知道 a - >一个必须是身份函数(或分歧)。类似的自由定理适用于许多其他多态函数。参数化也是更高级的基于类型的抽象技术的基础。例如,Haskell中的 ST sa 类型(state monad)以及相应的 runST 函数的类型,依靠 s 作为参数。这可以确保运行函数无法混淆状态的内部表示。



这对于高效实现也很重要。程序在运行时不必传递昂贵的类型信息( type erasure ),编译器可以为不同类型选择重叠表示。作为后者的一个例子,0和False以及()和[]在运行时都用0表示。这是不可能的,如果像你这样的功能被允许的话。


This is probably a very basic question, but ...

A function that's defined as, say

foo :: a -> Integer

denotes a function from any type to an Integer. If so, then in theory one should be able to define it for any type, like so

foo 1 = 10
foo 5.3 = 100
foo (x:xs) = -1
foo  _     = 0

But Haskell only allows a general definition, like foo a = 0.

And even if you restrict a to be one of a certain class of types, such as an instance of the Show typeclass :

foo :: (Show a) => a -> Integer

you still can't do something like

foo "hello" = 10
foo   _     = 0

even though "hello" :: [Char] is an instance of Show

Why is there such a restriction?

解决方案

It's a feature, and actually is very fundamental. It boils down to a property known as parametricity in programming language theory. Roughly, that means that evaluation should never depend on types that are variables at compile time. You cannot look at a value where you do not know its concrete type statically.

Why is that good? It gives much stronger invariants about programs. For example, you know from the type alone that a -> a has to be the identity function (or diverges). Similar "free theorems" apply to many other polymorphic functions. Parametricity also is the basis for more advanced type-based abstraction techniques. For example, the type ST s a in Haskell (the state monad), and the type of the corresponding runST function, rely on s being parametric. That ensures that the running function has no way of messing with the internal representation of the state.

It is also important for efficient implementation. A program does not have to pass around costly type information at run time (type erasure), and the compiler can choose overlapping representations for different types. As an example of the latter, 0 and False and () and [] are all represented by 0 at runtime. This wouldn't be possible if a function like yours was allowed.

这篇关于为什么Haskell不允许所有类型的函数定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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