gpt4 book ai didi

haskell - 如何在 Haskell 中部分定义函数签名?

转载 作者:行者123 更新时间:2023-12-03 05:56:30 30 4
gpt4 key购买 nike

起点:

fn :: [a] -> Int
fn = (2 *) . length

假设我们只想限制返回值,那么我们可以这样写:

fn list = (2 * length list) :: Int

仅限制参数怎么样?简单。

fn list = 2 * length (list :: [Char])

虽然这有效,但最好有签名顶部聚集,而不是分散在函数体周围。

这是我能达到的最接近的结果:

fnSig = undefined :: [Char] -> a
fn | False = fnSig
| True = (* 2) . length

基于http://okmij.org/ftp/Haskell/partial-signatures.lhs通过http://okmij.org/ftp/Haskell/types.html#partial-sigs

但是,我想要一个更干净的解决方案。更好地传达我的意图的东西是部分限制。例如这样的事情:

fn :: [Char] -> a
fn = (2 *) . length

或者也许:

fn :: [Char] -> _
fn = (2 *) . length

这可能吗?

编辑以进一步说明:

@GaneshSittampalam 在下面的评论中提出了一个重要观点。我正在寻找“一个介于完全没有类型签名和必须给出精确类型签名之间的折中方案”。因此,我不是在寻找基于 TypeClass 的答案,我只是希望 GHC 填充我的函数的未指定(或未完全限制)类型的空白。

编辑回应@WillNess

是的,像这样......

fn list = 2 * length list
where
_ = list :: [Char]

...可以工作,但仅适用于参数,并且仅当函数不是无点的时。有没有办法将此技术应用于无点函数或返回值?

编辑回应@Rhymoid

我受到启发,并尝试了 @Rhymoid 的想法,并想出了这个:

fn = (2 *) . length
where
_ = fn `asTypeOf` (undefined :: [Char] -> a)
_ = fn `asTypeOf` (undefined :: a -> Int)
_ = fn `asTypeOf` (undefined :: a -> b)
_ = fn `asTypeOf` (undefined :: a)

这种方法还限制了 fn 的类型签名,并且不会污染任何命名空间。

通常我们只有一个 asTypeOf 行,我只是添加了多个来展示这种方法的强大功能。

这比我想要的要笨拙一些,但我想即使没有语言的特定语法支持,我们也可以做到这一点,这非常巧妙。

@Rhymoid,如果您也喜欢它,请将其添加到您的答案中。 :)

最佳答案

抱歉 self 推销,但正是这个功能是博士最近一篇论文的主题。学生 Thomas Winant、我本人、Frank Piessens 和 Tom Schrijvers,最近由 Thomas 在 PADL 2014 研讨会上发表。完整论文请参见 here。该功能已经存在于其他一些语言中,但与 Haskell GADT 等功能的交互使其变得足够有趣,足以解决细节问题。

Thomas 正在致力于 GHC 的实现。自论文撰写以来,它已经得到了进一步的改进,但在 GHC 中实现“通配符约束”在技术上比我们预期的要困难一些。我们希望能够进一步研究它并联系 GHC 开发人员以使其采用,但这种情况是否发生可能取决于有多少人希望在 Haskell 中拥有该功能......

2015 年 4 月 14 日更新:经过 Thomas 的大量工作以及 SPJ 和其他 GHC 人员的投入,部分类型签名已在 GHC 7.10 中发布。 Thomas Winant 写了一篇关于如何使用它们的 an introductory blog post 文章。

关于haskell - 如何在 Haskell 中部分定义函数签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21658438/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com