将作为参数传递的函数应用于 Haskell 中的不同类型
Applying Function Passed as Argument to Different Types in Haskell
有什么方法可以将作为参数传递的函数应用于两种不同的类型?作为一个人为的例子,我可以用表达式 (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
是常量。
这个用例是将通用函数应用于树结构,其中每个节点都按类型参数化。
这可以使用 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)
有什么方法可以将作为参数传递的函数应用于两种不同的类型?作为一个人为的例子,我可以用表达式 (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
是常量。
这个用例是将通用函数应用于树结构,其中每个节点都按类型参数化。
这可以使用 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)