首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >熔断导线

熔断导线
EN

Stack Overflow用户
提问于 2014-10-29 16:55:33
回答 1查看 135关注 0票数 2

可穿纸在第18-19页给出了一个例子,它融合了一元论和一元遍历,这听起来很有趣,但我对他们的LaTex感到困惑。

代码语言:javascript
运行
复制
cciBody :: Char -> Count a
wciBody :: Char -> (|M| (State Bool) DotInASquare Count) a

其惊人的结果是:

代码语言:javascript
运行
复制
(traverse cciBody) xInACircle (traverse wciBody)

与以下相同:

代码语言:javascript
运行
复制
traverse (cciBody xInACircle wciBody)

我认为这种结果是:

代码语言:javascript
运行
复制
Count XInASquare (|M| (State Bool) DotInASquare Count) [a]

但不是百分之百确定。会说Emoji语言的人能告诉我在Haskell应该怎么看吗?

更新

我认为xInACircle可能是一个infix sequenceA。这种类型是匹配的。或者可能只是(,),它是Traversable的一个实例。这绝对不是<*>,尽管结果看起来有点像t (x <*> y) = t x <*> t y,但是在论文中,他们并没有为<*>使用展翅。

更新2

xInACircle的类型是(函子m,函子n)⇒(a→m b)→(a→n b)→(a→(m XInASquare n) b)。让你想起什么了吗?不是我。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-29 21:29:21

您对类型签名中使用的运算符感到困惑。基本上,Haskell语法中相同的规则适用于这些:第一优先级是括号,第二优先级是“应用程序”,最后优先级是“运算符”。就像你写的一样:

代码语言:javascript
运行
复制
f 3 + g 4

在数学术语中,我们以f(3) + g(4)的形式编写,在Haskell中有一个标志来启用以冒号开头的infix类型操作符(-XTypeOperators),这样您就可以编写类似于f :: a :* b -> b :* [a]的表达式,而不是f :: Star a b -> Star b [a]。它只是至少有两个参数的参数类型构造函数的另一种语法。(我想,由于->已经是一个infix类型的构造函数,这几乎不是新闻。)我们也可以将它们写成Comp a bProd a b

向上箭头和向下箭头是在论文中定义为类型类的一部分的函数,但我不喜欢Haskell真正接受这些函数所需要的所有语用,所以我将在下面的代码中解释它们。下面是使用CompProd而不是它们的运算符作为有效Haskell文件的所有相关定义:

代码语言:javascript
运行
复制
import Control.Applicative (Applicative, (<$>), (<*>), pure, WrappedMonad(..), Const(..))
import Data.Traversable (traverse)
import Control.Monad.State.Lazy (State, state, runState)
import Data.Char (isSpace)
import Data.Monoid (Monoid(..))

instance Monoid Integer where
    mempty = 0
    mappend = (+)

-- chained functors
newtype Comp m n a = Comp {runComp :: m (n a)}
instance (Functor m, Functor n) => Functor (Comp m n) where
    fmap f = Comp . fmap (fmap f) . runComp
instance (Applicative m, Applicative n) => Applicative (Comp m n) where
    pure = Comp . pure . pure
    Comp mnf <*> Comp mnx = Comp ((<*>) <$> mnf <*> mnx)

-- outer product of functors
data Prod m n a = Prod {pfst :: m a, psnd :: n a}
instance (Functor m, Functor n) => Functor (Prod m n) where
    fmap f (Prod ma na) = Prod (fmap f ma) (fmap f na)
instance (Applicative m, Applicative n) => Applicative (Prod m n) where
    pure x = Prod (pure x) (pure x)
    Prod mf nf <*> Prod mx nx = Prod (mf <*> mx) (nf <*> nx)

-- page 19,20

type Count = Const Integer
count :: a -> Count b
count _ = Const 1

cciBody :: Char -> Count a
cciBody = count

cci :: String -> Count [a]
cci = traverse cciBody

test :: Bool -> Integer
test b = if b then 1 else 0

lciBody :: Char -> Count a
lciBody c = Const (test (c == '\n'))

lci :: String -> Count [a]
lci = traverse lciBody

wciBody :: Char -> Comp (WrappedMonad (State Bool)) Count a
wciBody c = Comp (fmap Const (WrapMonad $ state $ updateState c)) where
    updateState :: Char -> Bool -> (Integer, Bool)
    updateState c w = let s = not (isSpace c) in (test (not w && s), s)

wci :: String -> Comp (WrappedMonad (State Bool)) Count [a]
wci = traverse wciBody

runWci :: String -> Integer
runWci s = fst $ runState (fmap getConst $ unwrapMonad $ runComp $ wci s) False

如果您不清楚从哪里来的函数,我会将导入限制在顶部,所以在那里查找(或者使用Hoogle)找到它们的定义。

您所调用的运算符 xInACircle是一个运算符,它接受a -> m ba -> n b并生成函数a -> Prod m n b。此产品类型同时包含应用程序mn的结果。一旦你理解了x-in-a-方型,你就会明白x-in-a-a-a运算符。与(Monoid m) => Applicative ((,) m)实例不同,在第二个参数中只有fmaps和<*>s,两个抽象函子的Prod是一对函子,fmap<*>对这两个参数都是。这是一对(m a, n a),其中mn都是可应用的。

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

https://stackoverflow.com/questions/26636328

复制
相关文章

相似问题

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