不同数量参数的函数之间的统一接口
Unified interface between functions of different number of arguments
我有两个这样的函数:
foo :: a -> b -> x -> x
bar :: c -> y -> y
我想将它们统一到一个界面中,这样它们就可以同名了。在我的例子中,保证 x
和 y
类型不同(但可能有多个 x
)。所以它看起来是可能的。但是在部分应用的情况下,我所有的尝试都有错误的类型推断:(
你能帮忙想出这个案例的界面吗?
我以前的尝试是这样的,但这个解决方案需要明确的类型应用程序来消除歧义:
class Insert s i where
insert :: i
instance (Ord k, i ~ (k -> Set k -> Set k)) => Insert Set i where
insert = Set.insert
我猜下面的方法可能有效。根据评论,这仍然是一个糟糕、糟糕、糟糕的想法。如果你真想这样写Haskell,那你就真的不想写Haskell.
无论如何,我们的想法是为class提供一个类型:
insert :: (Ord k) => k -> v -> a
在所有三个参数中进行参数化,并指定 a
确定 k
和 v
的函数依赖性。在您的情况下,a ~ (Map k' v' -> Map k' v')
表示 k ~ k'
和 v ~ v'
,而 a ~ Set t
表示 k ~ t
和 v ~ Set t
。
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies,
NoMonomorphismRestriction #-}
module UnifiedInsert where
-- insert :: Ord k => k -> v -> Map k v -> Map k v
-- insert :: Ord a => a -> Set a -> Set a
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Set (Set)
import qualified Data.Set as Set
class Insert k v a | a -> k, a -> v where
insert :: (Ord k) => k -> v -> a
instance Insert k (Set k) (Set k) where
insert = Set.insert
instance Insert k v (Map k v -> Map k v) where
insert = Map.insert
fromList = foldr insert mempty
foo1 :: Set Int
foo1 = fromList [1..10]
请注意,类型检查器可以推断出函数 fromList
的类型(即使 foo1
从程序中删除),只要关闭单态限制。它将具有相当荒谬的类型:
fromList :: (Foldable t, Insert k v v, Ord k, Monoid v) => t k -> v
确实可以根据需要专门用于 Ord a => [a] -> Set a
。
我有两个这样的函数:
foo :: a -> b -> x -> x
bar :: c -> y -> y
我想将它们统一到一个界面中,这样它们就可以同名了。在我的例子中,保证 x
和 y
类型不同(但可能有多个 x
)。所以它看起来是可能的。但是在部分应用的情况下,我所有的尝试都有错误的类型推断:(
你能帮忙想出这个案例的界面吗?
我以前的尝试是这样的,但这个解决方案需要明确的类型应用程序来消除歧义:
class Insert s i where
insert :: i
instance (Ord k, i ~ (k -> Set k -> Set k)) => Insert Set i where
insert = Set.insert
我猜下面的方法可能有效。根据评论,这仍然是一个糟糕、糟糕、糟糕的想法。如果你真想这样写Haskell,那你就真的不想写Haskell.
无论如何,我们的想法是为class提供一个类型:
insert :: (Ord k) => k -> v -> a
在所有三个参数中进行参数化,并指定 a
确定 k
和 v
的函数依赖性。在您的情况下,a ~ (Map k' v' -> Map k' v')
表示 k ~ k'
和 v ~ v'
,而 a ~ Set t
表示 k ~ t
和 v ~ Set t
。
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies,
NoMonomorphismRestriction #-}
module UnifiedInsert where
-- insert :: Ord k => k -> v -> Map k v -> Map k v
-- insert :: Ord a => a -> Set a -> Set a
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Set (Set)
import qualified Data.Set as Set
class Insert k v a | a -> k, a -> v where
insert :: (Ord k) => k -> v -> a
instance Insert k (Set k) (Set k) where
insert = Set.insert
instance Insert k v (Map k v -> Map k v) where
insert = Map.insert
fromList = foldr insert mempty
foo1 :: Set Int
foo1 = fromList [1..10]
请注意,类型检查器可以推断出函数 fromList
的类型(即使 foo1
从程序中删除),只要关闭单态限制。它将具有相当荒谬的类型:
fromList :: (Foldable t, Insert k v v, Ord k, Monoid v) => t k -> v
确实可以根据需要专门用于 Ord a => [a] -> Set a
。