我有一个新类型来代表Hughes的列表(即列表构造):
newtype Hughes a = Hughes {unHughes :: [a] -> [a]}
有一些功能可以解决它:
mkHughes :: [a] -> Hughes a
mkHughes = Hughes . (++)
runHughes :: Hughes a -> [a]
runHughes h = unHughes h []
Monoid
实例就像上面的函数一样简单:
instance Monoid (Hughes a) where
mempty = Hughes id
mappend (Hughes f) (Hughes g) = Hughes (f . g)
...但是当我到达Functor
和Applicative
个实例时出现问题。这是我到目前为止所提出的:
instance Functor Hughes where
fmap f (Hughes h) = Hughes $ unsafeCoerce $ fmap f . h
instance Applicative Hughes where
pure = Hughes . (:)
(<*>) (Hughes f) (Hughes v) = Hughes $ unsafeCoerce $
(<*>) <$> f <*> unsafeCoerce v
我遇到的问题是我不喜欢使用unsafeCoerce
。有没有办法设计Functor
实例而不使用它,或者它是不可避免的?
此外,我如何为此数据类型实现Monad
实例?
编辑:与DList
包不同,我希望保持性能提升,即不评估[a] -> [a]
,而是映射它。
答案 0 :(得分:7)
无法实施def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :last_name, :age, :height, :weight, :gender])
end
个实例。
让我们来看看Functor Hughes
:
Hughes
我们可以看到参数data Hughes a = Hughes ([a] -> [a])
^
在标记的位置显示逆变。只有当最后一个类型参数的所有外观都是协变的时,a
实例才会存在。
基本上,您被要求定义一个函数Functor
。问题是您无法对fmap :: (a -> b) -> ([a] -> [a]) -> [b] -> [b]
执行任何操作,因此没有接受[b]
或[b]
的功能。你可以忽略它,但是仿函数法b
将不会成立。
对于DList,fmap id = id
实例是有效的,因为实现不导出实际的数据构造函数,只导出智能构造函数。因此,您无法构造作为任意列表处理函数的dlist值。使用提供的智能构造函数,您只能构造与Functor
同构的dlists,这就是函数法所适用的原因。
如果你以某种方式将构造函数破解(带入)范围,你会发现仿函数法实际上并不适用于任意函数,例如[a]
如果fmap id x /= x
是某种东西比如x
。