【问题标题】:Why can't the compiler deduce the Functor type in the Free Applicative examples?为什么编译器不能在 Free Applicative 示例中推断出 Functor 类型?
【发布时间】: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 freturn 定义了>>=ThrowE,因此您可以使用FunctorApplicative 的默认实现。
  • 我不认为这是类型错误的原因。好吧,我现在有点明白他们的意思了,但真正让我吃惊的是,当我将 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,也不适用于 EqShow,... 或任何其他类)。
  • @chi,好吧,您确实可以使用最新的编译器免费获得两个非标准类。 TypeableCoercible 不需要显式派生。
  • 请看编辑。

标签: haskell applicative free-monad


【解决方案1】:
module Main where

data Toy b next =
    Output b next
  | Bell next
  | Done

instance Functor f => Functor (FixE f) where
  fmap f (Fix x) = Fix (fmap (fmap f) x)
  fmap f (Throw e) = Throw (f e)

data FixE f e = Fix (f (FixE f e)) | Throw e

-- 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

-- Applicative function
applicativeFixE :: (Functor f) => FixE f (e1 -> e2) -> FixE f e1 -> FixE f e2
applicativeFixE (Fix f) b = Fix (fmap (`applicativeFixE` b) f)
applicativeFixE (Throw f) b = fmap f b

main :: IO()
main = print "Hello."

基于 cmets,我设法实现了 applicative 功能。我不完全确定为什么上述方法与我尝试过的一些替代方法相比仍然有效,但它会进行类型检查。

谢谢大家。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 2012-03-26
    • 1970-01-01
    • 2021-03-11
    相关资源
    最近更新 更多