在Haskell中引用多态性的透明度 [英] Referential transparency with polymorphism in Haskell

查看:146
本文介绍了在Haskell中引用多态性的透明度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个函数:

  f :: Int  - > (Rational,Integer)
fb =((toRational b)+1,(toInteger b)+1)

我想像这样抽象出(+1):

  f :: Int  - > (Rational,Integer)
fb =(h(toRational b)
,h(toInteger b))
where h =(+1)

这不会很明显,但如果我指定类型签名,它将起作用:

  f :: Int  - > (Rational,Integer)
f b =(h(toRational b)
,h(toInteger b))
where h :: Num a => a - > a
h =(+1)

假设我现在想通过传递h作为参数:

  f :: Num a => Int  - > (a  - > a) - > (Rational,Integer)
f b g =(h(toRational b)
,h(toInteger b))
其中h :: Num a => a - > a
h = g

我得到一个错误,即内部a与a不同外部的。



有谁知道如何正确编写这个函数吗?
我想将一个多态函数 g 传递给 f ,并以多态方式使用它。



我现在在多个不同的项目中遇到过这种情况,而且我找不到一个好的解决方案。

解决方案

}
f :: Int - > (全部数量a => a - > a) - > (Rational,Integer)
f b g =(h(toRational b)
,h(toInteger b))
其中h :: Num a => a - > a
h = g

当然可以变成:

  f :: Int  - > (全部数量a => a  - > a) - > (Rational,Integer)
f b g =(g(toRational b)
,g(toInteger b))


Say I have a function:

f :: Int -> (Rational, Integer)
f b = ((toRational b)+1,(toInteger b)+1)

I want to abstract away the (+1) like so:

f :: Int -> (Rational, Integer)
f b = (h (toRational b)
      ,h (toInteger b))
    where h = (+1)

This wont work obviously, but if I specify the type signature it will work:

f :: Int -> (Rational, Integer)
f b = (h (toRational b)
      ,h (toInteger b))
    where h :: Num a => a -> a
          h = (+1)

Say I now want to further abstract the function by passing h as a parameter:

f :: Num a => Int -> (a -> a) -> (Rational, Integer)
f b g = (h (toRational b)
        ,h (toInteger b))
    where h :: Num a => a -> a
          h = g

I get an error that the inner a is not the same a as the outer one.

Does anyone know how to write this function correctly? I want to pass a polymorphic function g to f and use it polymorphically.

I have encountered this situation multiple times now in very different projects, and I could not find a good solution.

解决方案

I found the solution: using the forall quantifier like so:

{-# LANGUAGE RankNTypes #-}
f :: Int -> (forall a. Num a=> a -> a) -> (Rational, Integer)
f b g = (h (toRational b)
        ,h (toInteger b))
    where h :: Num a => a -> a
          h = g

Which of course can be turned into:

f :: Int -> (forall a. Num a=>a -> a) -> (Rational, Integer)
f b g = (g (toRational b)
        ,g (toInteger b))

这篇关于在Haskell中引用多态性的透明度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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