从(a - > b - > c)和(Wire s e a a b)构建(Wire s e m a c)

时间:2014-12-21 06:53:45

标签: haskell netwire

作为一个简单的例子,我有这个。

import Prelude hiding ((.))
import FRP.Netwire
import Control.Wire

f :: Int -> Char -> String
f = replicate

w :: => Wire s e m Int Char
w = mkSF_ fromInt
    where
        fromInt :: Int -> Char
        fromInt 1 = 'a'
        fromInt 2 = 'b'
        fromInt _ = '_'

w2 :: Wire s e m Int String
w2 = undefined -- This is where I get stuck

我希望能够创建从Int到Strings的电线。

我认为应该很容易,但我没有运气。

3 个答案:

答案 0 :(得分:2)

您需要拆分原始Int输入,并将其展示给warr f。解释它的最简单方法是使用箭头符号:

{-# LANGUAGE Arrows #-}
w2 :: (Monad m) => Wire s e m Int String
w2 = proc n -> do
    c <- w -< n
    returnA -< f n c

现在,我不知道Netwire的第一件事,但Monad m约束存在,因为Arrow Wire s e m w2 :: (Monad m) => Wire s e m Int String w2 = arr (uncurry f) . (id &&& w) 实例需要这样做。

如果你想摆脱箭头符号,上面的内容可以改写为

-- I want to write (Arrow (~>)) => (a -> b -> c) -> (a ~> b) -> (a ~> c)!
-- Damn you TypeOperators!
arr2 :: (Arrow arr) => (a -> b -> c) -> arr a b -> arr a c
arr2 f arr = proc x -> do
    y <- arr -< x
    returnA -< f x y

当然,您可以将概念概括为这种抽象:

{{1}}

答案 1 :(得分:2)

另一种选择是使用应用语法,甚至更清晰,imo

w2 :: Monad m => Wire s e m Int String
w2 = f <$> id <*> w

这概括为

(Category cat, Applicative (cat a)) => (a -> b -> c) -> cat a b -> cat a c

请注意,每Arrow都会产生上述约束。

答案 2 :(得分:1)

我想出的另一个解决方案是

w2 :: Monad m => Wire s e m Int String
w2 = liftA2 ($) (mkSF_ f) w
-- or w2 = liftA2 ($) (arr f) w
-- or w2 = arr f <*> w