如果你想附加两个类型为(a - > mb)的函数,这样你只能得到一个相同类型的函数来追加两个结果,你可以使用Kleisli来做到这一点:
instance (Monad m, Monoid b) => Monoid (Kleisli m a b) where
mempty = Kleisli (\_ -> return mempty)
mappend k1 k2 =
Kleisli g
where
g x = do
r1 <- runKleisli k1 x
r2 <- runKleisli k2 x
return (r1 <> r2)
Run Code Online (Sandbox Code Playgroud)
但是,目前没有定义这样的实例Control.Arrow.通常,在Haskell,我怀疑有一个很好的理由,但找不到哪一个.
这个问题是相当类似,这一个.但是,使用Monoid我没有看到定义实例的方法,例如:
instance (Monad m, Monoid b) => Monoid (a -> m b) where
[...]
Run Code Online (Sandbox Code Playgroud)
因为已经存在一个实例:
instance Monoid b => Monoid (a -> b) where
[...]
Run Code Online (Sandbox Code Playgroud) 我正在寻找一个关于使用Haskell GHC.Generics包的selName函数的简单示例.
考虑以下记录类型:
{-# language DeriveGeneric #-}
data Person = Person {
firstName :: String
, lastName :: String
, age :: Integer
} deriving(Generic
Run Code Online (Sandbox Code Playgroud)
如何使用selName函数获取firstName选择器的名称?
我们有以下数据类型:
data Foo1 a = Foo1
data Foo2 a = Foo2 (Foo3 a)
data Foo3 a = C1 (Foo1 a) | C2 Int
Run Code Online (Sandbox Code Playgroud)
现在我们希望能够从Foo1或Int获得Foo3.解决方案可以是使用类型类:
class ToFoo3 a where
toFoo3 :: a -> Foo3 b -- Here start the problems with this phantom type b...
instance ToFoo3 (Foo1 b) where
toFoo3 foo1 = C1 foo1
instance ToFoo3 Int where
toFoo3 int = C2 int
Run Code Online (Sandbox Code Playgroud)
在这里,编译器抱怨(正确!)它不能将b与b1匹配,因为类定义中的Foo3的"b"与实例中的Foo1的"b"不同.
有办法解决这个问题吗?
mappend函数只是关联操作的一个特例,其中两个元素属于同一类型.为什么没有包提出没有这种条件的关联函数的实现?
使用多参数类型类扩展时,这将非常简单:
{-# Language MultiParamTypeClasses #-}
module Append where
class Append a b where
(<->) :: a -> b -> a
Run Code Online (Sandbox Code Playgroud)
然后,根据实例的实现,它将允许将Int与String连接:
"I am " <-> 42
> "I am 42"
Run Code Online (Sandbox Code Playgroud)
或者为数据记录类型添加可选参数:
data MyType = MyType {_option :: Maybe String}
myType = MyType Nothing
myTypeWithOption = myType <-> "Hello!"
Run Code Online (Sandbox Code Playgroud)
我试图搜索Hoogle,Hayoo!并在网上但找不到这样的功能.
所以:a)它存在吗?b)如果不是为什么?