【发布时间】:2016-09-30 16:21:19
【问题描述】:
module Main where
data Toy b next =
Output b next
| Bell next
| Done
data FixE f e = Fix (f (FixE f e)) | Throw e
-- The working monadic function
catch :: (Functor f) => FixE f e1 -> (e1 -> FixE f e2) -> FixE f e2
catch (Fix x) f = Fix (fmap (`catch` f) x)
catch (Throw e) f = f e
-- Type error
applicate_fixe :: (Functor f) => FixE f (e1 -> e2) -> FixE f e1 -> FixE f e2
applicate_fixe a b = a `catch` (`fmap` b)
-- Type error
applicate_fixe' :: (Functor f) => FixE f (e1 -> e2) -> FixE f e1 -> FixE f e2
applicate_fixe' (Throw f) b = fmap f b
applicate_fixe' (Fix f) b = Fix (fmap (`applicate_fixe` b) f)
main :: IO()
main = print "Hello."
C:\!Various_Exercises\Haskell_Exercises\Free_Monad_Stuff\test.hs: 15, 33
Could not deduce (Functor (FixE f)) arising from a use of `fmap'
from the context (Functor f)
bound by the type signature for
applicate_fixe :: Functor f =>
FixE f (e1 -> e2) -> FixE f e1 -> FixE f e2
at test.hs:14:19-76
In the second argument of `catch', namely `(`fmap` b)'
In the expression: a `catch` (`fmap` b)
In an equation for `applicate_fixe':
applicate_fixe a b = a `catch` (`fmap` b)
C:\!Various_Exercises\Haskell_Exercises\Free_Monad_Stuff\test.hs: 18, 31
Could not deduce (Functor (FixE f)) arising from a use of `fmap'
from the context (Functor f)
bound by the type signature for
applicate_fixe' :: Functor f =>
FixE f (e1 -> e2) -> FixE f e1 -> FixE f e2
at test.hs:17:20-77
In the expression: fmap f b
In an equation for applicate_fixe':
applicate_fixe' (Throw f) b = fmap f b
我要离开this tutorial,试图找出 Free Monad,作为练习,我也在尝试做 Applicative 函数。老实说,我不确定这些错误是什么意思。
我也不确定data FixE f e = Fix (f (FixE f e)) | Throw e 的类型签名应该是什么。起初我以为f (FixE f e) 应该是一个元组,但它看起来确实是一个参数,因此(FixE f e) 部分实际上是第一个f 的类型参数。但如果是这种情况,FixE f e 中的 f 是否也需要类型参数?
编辑:
applicate_fixe :: (Functor f) => FixE f (e1 -> e2) -> FixE f e1 -> FixE f e2
applicate_fixe (Fix f) b = Fix (fmap (`applicate_fixe` b) f) -- Works as the f argument in fmap is a functor
applicate_fixe (Throw f) (Fix b) = fmap f b -- The b is of type f (FixE f e1) so it is clearly a functor and yet the type system rejects it.
首先,我不明白最后一部分。还有到底应该定义什么函子的实例? f 在上面的定义中应该已经有了这个约束。
Edit2:也许你的意思是 FixE 应该有一个 Functor 实例。
instance Functor f => Functor (FixE f) where
fmap f (Fix x) = fmap f x -- Type error
fmap f (Throw e) = Throw (f e)
这是我最好的镜头,但它抱怨第一行中的类型 f 太死板。
【问题讨论】:
-
您需要定义
Functor的实际实例才能使用fmap。您已经为FixE f和return定义了>>=是ThrowE,因此您可以使用Functor和Applicative的默认实现。 -
我不认为这是类型错误的原因。好吧,我现在有点明白他们的意思了,但真正让我吃惊的是,当我将
applicate_fixe'' (Throw f) b = fmap f b更改为applicate_fixe' (Throw f) (Fix b) = fmap f b时,我仍然会收到类型错误。这令人困惑,因为Fix b中的b确实是一个函子,但编译器仍然不会接受它。 -
您需要明确添加
instance .. => Functor (...) where fmap = ...或使用deriving机制(可能是独立的)。如果您不这样做,Haskell 不会为您的类型配备任何实例(不适用于Functor,也不适用于Eq、Show,... 或任何其他类)。 -
@chi,好吧,您确实可以使用最新的编译器免费获得两个非标准类。
Typeable和Coercible不需要显式派生。 -
请看编辑。
标签: haskell applicative free-monad