【问题标题】:Applying Function Passed as Argument to Different Types in Haskell将作为参数传递的函数应用于 Haskell 中的不同类型
【发布时间】:2016-02-05 03:23:43
【问题描述】:

有没有办法将作为参数传递的函数应用于两种不同的类型?作为一个人为的例子,我可以使用表达式(Just 3, Just True) 创建一个(Maybe Int, Maybe Bool),但是如果我尝试使用该函数使这种行为更通用

generic :: (a -> Maybe a) -> (Maybe Int, Maybe Bool)
generic f = (f 3, f True)

为了让我能够执行generic Just 之类的操作,编译器会报错,因为类型变量a 是常量。

这种情况的用例是将通用函数应用于树结构,其中每个节点都由类型参数化。

【问题讨论】:

    标签: haskell parametric-polymorphism


    【解决方案1】:

    这可以使用 rank-2 多态性来实现,如下所示:

    {-# LANGUAGE Rank2Types #-}
    generic :: (forall a. a -> Maybe a) -> (Maybe Int, Maybe Bool)
    generic f = (f 3, f True)
    

    通常你需要一些类型类限制(不是因为generic 的实现需要它,而是因为调用者无法传递适用于所有类型的参数),例如

    genericNum :: (forall a. Num a => a -> a) -> (Int, Integer)
    genericNum f = (f 3, f 9)
    

    【讨论】:

    • 我不知道你对此有何感想,但当我使用启用forall 的扩展程序时,我总是打开ScopedTypeVariables;否则我可能会在路上感到困惑。
    • 完美,非常感谢!你知道通过所有这些现代语言扩展的任何好的资源吗?我能找到的所有 Haskell 书籍大多与 Haskell 98 相关,而 Haskell 文档可能非常令人筋疲力尽......
    • @igorbark 如果你想要所有的扩展,没有比the horse's mouth更好的来源了。
    • @igorbark:似乎有一些人已经使用了my explanation of RankNTypes over here
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    • 2018-01-04
    • 1970-01-01
    • 2022-10-06
    • 2019-03-05
    • 2018-09-24
    相关资源
    最近更新 更多