gpt4 book ai didi

没有参数的 Haskell 多变量函数

转载 作者:行者123 更新时间:2023-12-03 23:46:40 24 4
gpt4 key购买 nike

我正在尝试在 Haskell 中创建一个多变量函数,我使用了 this回答创建一个基本函数。
这是函数的代码:

class SumRes r where 
sumOf :: Integer -> r

instance SumRes Integer where
sumOf = id

instance (Integral a, SumRes r) => SumRes (a -> r) where
sumOf x = sumOf . (x +) . toInteger

但问题是:当不带任何参数调用该函数时,它不起作用。
Couldn't match expected type 'Integer' with actual type 'Integer -> r0'
Probable cause: 'sumOf' is applied to too few arguments

例如,我希望能够写 sumOf :: Integer并让这个函数返回 0 .

我该怎么做?

最佳答案

最简单的版本只适用于 Integer结果。

简单的方法

这适用于您已经编写的内容,并利用了 0 的事实。是加法的身份。

class SumRes r where
sumOf' :: Integer -> r

instance SumRes Integer where
sumOf' = toInteger

instance (Integral b, SumRes r) => SumRes (b -> r) where
sumOf' a b = sumOf' $! a + toInteger b

sumOf :: SumRes r => r
sumOf = sumOf' 0

两个实例, Integerb -> r ,本质上不重叠。

更难的方式

要获得更通用的结果类型,您需要一种稍微不同的方法,因为如果 Integer,上述两个实例会混在一起。被类型变量替换。你可以用 MultiParamTypeClasses 来做到这一点和 TypeFamilies .
{-# LANGUAGE ScopedTypeVariables, AllowAmbiguousTypes, DataKinds,
KindSignatures, TypeApplications, MultiParamTypeClasses,
TypeFamilies, FlexibleInstances #-}

module SumRes2 where

data Nat = Z | S Nat
class SumRes (c :: Nat) r where
sumOf' :: Integer -> r

type family CountArgs a :: Nat where
CountArgs (_ -> r) = 'S (CountArgs r)
CountArgs _ = 'Z

instance Num r => SumRes 'Z r where
sumOf' = fromInteger

instance (Integral b, SumRes n r) => SumRes ('S n) (b -> r) where
sumOf' a b = sumOf' @n (a + toInteger b)

sumOf :: forall r n. (SumRes n r, CountArgs r ~ n) => r
sumOf = sumOf' @n 0

唯一的限制是,如果您有 Integral函数类型的实例,不能使用 sumOf生产它。不过这应该不是问题。我用过 TypeApplicationsAllowAmbiguousTypes为简洁起见,但您当然可以使用代理传递或 Tagged反而。

关于没有参数的 Haskell 多变量函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46078682/

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