首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么定义一个值未知的Choice实例失败?

为什么定义一个值未知的Choice实例失败?
EN

Stack Overflow用户
提问于 2018-02-18 17:36:50
回答 2查看 63关注 0票数 2

更新:我在这里内联代码。

我正在尝试定义一个Data.Profunctor.Choice的实例,其中right是通过调用left来定义的,但是由于某种原因,编译器报告left是未知的。

代码语言:javascript
复制
newtype StateTrans s i o = ST (Tuple s i → Tuple s o)

instance stFunctor ∷ Functor (StateTrans s a) where
  map f (ST st) = ST $ second f <<< st

instance stProfunctor ∷ Profunctor (StateTrans s) where
  dimap f g (ST st) = ST $ second g <<< st <<< second f

instance stChoice ∷ Choice (StateTrans s) where
  left (ST f) = ST lf
    where
    lf (Tuple s (Left a)) = let (Tuple s' b) = f (Tuple s a)
                            in Tuple s' (Left b)
    lf (Tuple s (Right c)) = Tuple s (Right c)
  -- Fails to compile with: Unknown value left
  right f = arr mirror <<< left f <<< arr mirror
    where
    mirror Left x = Right x
    mirror Right x = Left x

这可能是一个愚蠢的错误,但是我已经看了我的代码很长时间了,我不知道哪里出了问题。

(次要的和不相关的:在leftRight示例中,我必须对值进行解包和重新打包,以便它与类型对齐。添加类型归属也无法编译。)

奇怪的是,我对Strong做同样的事情没有问题,请看:

代码语言:javascript
复制
instance stStrong ∷ Strong (StateTrans s) where
  first (ST f) = ST ff
    where
    ff (Tuple s (Tuple a c)) = let (Tuple s' b) = f $ Tuple s a
                               in Tuple s' (Tuple b c)
  second f = arr swap <<< first f <<< arr swap
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-19 18:08:03

我不是100%确定,因为粘贴的代码片段不包括导入,但我怀疑您有一个Data.Profunctor.Choice (class Choice)而不是Data.Profunctor.Choice (class Choice, left, right)的导入。

导入类不会隐式导入其成员,即使可以在不这样做的情况下在实例中定义它们。

票数 3
EN

Stack Overflow用户

发布于 2018-02-19 02:26:27

首先,要使用arr,您需要为StateTrans s声明Category实例

代码语言:javascript
复制
instance stSemigroupoid :: Semigroupoid (StateTrans s) where
  compose (ST f1) (ST f2) = ST $ f1 <<< f2

instance stCategory :: Category (StateTrans s) where
  id = ST $ \x -> x

对于第二步,我需要添加更多的类型注释(不确定为什么它们是必要的,但是这样构建成功了):

代码语言:javascript
复制
choiceLeft :: forall input output a s. (StateTrans s) input output -> (StateTrans s) (Either input a) (Either output a)
choiceLeft (ST f) = ST lf
  where
    lf (Tuple s (Left a))  = let (Tuple s' b) = f (Tuple s a)
                             in Tuple s' (Left b)
    lf (Tuple s (Right c)) = Tuple s (Right c)

choiceRight :: forall input output t s. (StateTrans s) input output -> (StateTrans s) (Either t input) (Either t output)
choiceRight f = amirror <<< choiceLeft f <<< amirror
  where
    mirror :: forall a b. Either a b -> Either b a
    mirror (Left x)  = Right x
    mirror (Right x) = Left x
    amirror :: forall a b. StateTrans s (Either b a) (Either a b)
    amirror = arr mirror

instance stChoice ∷ Choice (StateTrans s) where
  left  = choiceLeft
  right = choiceRight

注:使用PureScript版本0.11.7purescript-profunctor版本3.2.0

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48850240

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档