小编Mok*_*sha的帖子

Monad有没有MonadFix的实例?

问题主要在标题中.似乎mfix可以为任何monadic计算定义,即使它可能有所不同:

mfix :: (a -> m a) -> m a
mfix f = fix (join . liftM f)
Run Code Online (Sandbox Code Playgroud)

这个结构有什么问题?另外,为什么MonadMonadFixtypeclass分开(即什么类型有一个实例Monad但没有MonadFix?)?

monads haskell monadfix

13
推荐指数
2
解决办法
463
查看次数

如何将IO操作的结果注入非IO monadic计算中

我有一点建筑问题,我想看看是否有一个可以帮助我的常见模式或抽象.我正在编写一个游戏引擎,用户可以将游戏循环指定为表单的monadic计算:

gameLoop :: TimeStep -> a -> Game a
Run Code Online (Sandbox Code Playgroud)

其中Game单子有绘画,改造,并与一般的发动机接口一堆接入点.然后,我还提供了一个用户调用来运行模拟的函数

runGame :: (TimeStep -> a -> Game a) -> a -> IO a
Run Code Online (Sandbox Code Playgroud)

该库的主要设计目标之一是不创建类型类Game的实例MonadIO.这是为了防止用户通过更改底层图形调用的状态或在不期望的情况下加载内容来自我拍摄.但是,经常有一些用例,IO a在游戏循环开始后,a的结果很有用.特别是,会想到用程序生成的图形元素产生敌人.

因此,我想允许用户使用类似于以下界面的内容来请求资源:

data ResourceRequestResult a
  = NotLoaded
  | Loaded a

newtype ResourceRequest a = ResourceRequest {
  getRequestResult :: Game (ResourceRequestResult a)
}

requestResource :: IO a -> Game (ResourceRequest a)
Run Code Online (Sandbox Code Playgroud)

有了这个,我想分叉一个线程来加载资源并将结果传递给Gamemonad 的上下文并返回给用户.主要目标是我决定何时发生IO动作 - 我希望它在某个地方,而不是在游戏循环的中间.

我想到的一个想法是在monad之上放置另一个用户定义的monad变换器Game...类似于

newtype ResourceT r m a = ResourceT …
Run Code Online (Sandbox Code Playgroud)

monads haskell monad-transformers

11
推荐指数
2
解决办法
459
查看次数

mapA如何在Haskell中使用Stream Function Arrow?

背景

我一直在阅读约翰·休斯的" 箭头编程",我觉得直到下面的使用mapA的例子我才能直截了当:

>runSF (mapA (delay 0)) [[1,2,3],[4,5,6],[7,8,9]]
[[0,0,0],[1,2,3],[4,5,6]]
Run Code Online (Sandbox Code Playgroud)

其中runSF从StreamFunction箭头中提取流函数,定义为:

newtype SF a b = SF {runSF :: [a]->[b]}
Run Code Online (Sandbox Code Playgroud)

延迟定义为:

delay x = SF (init . (x:))
Run Code Online (Sandbox Code Playgroud)

SF是ArrowChoice的一个实例(声明mapA),因此是Arrow的一个实例.

我的理解

mapA :: arr a b -> arr [a] [b]
delay :: SF a b
Run Code Online (Sandbox Code Playgroud)

这样delay只需要用它的第一个参数预先设定它的第二个参数.

因此,mapA (delay 0)应该返回一个获取[[a]]并返回的SF箭头[[b]]

mapA (delay 0) :: SF [[a]] [[b]]
Run Code Online (Sandbox Code Playgroud)

我希望这会产生的"电路"是:

mapA的控制流程图(延迟0)

数字标记过程的一部分:

  1. 对于任何非空list x,listcase都会发出Right(x, xs).对于空列表,listcase将发出Left(),终端案例.
  2. 标记的值Right将传递到下半部分.标记的值 …

haskell arrows

10
推荐指数
1
解决办法
321
查看次数

转换4x4字节矩阵的最快方法

我有一个4x4字节块,我想使用通用硬件进行转置.换句话说,对于字节AP,我正在寻找最有效(就指令数量而言)的方式

A B C D
E F G H
I J K L
M N O P
Run Code Online (Sandbox Code Playgroud)

A E I M
B F J N
C G K O
D H L P
Run Code Online (Sandbox Code Playgroud)

我们可以假设,我有有效指针指向A,E,I,并M在内存中(这样从读取32位将让我的包含整数字节ABCD).

由于对大小和数据类型的限制,这不是此问题的重复.我的矩阵的每一行都可以适合32位整数,我正在寻找可以使用通用硬件快速执行转置的答案,类似于SSE宏的实现_MM_TRANSPOSE4_PS.

c c++ optimization bit-manipulation matrix

7
推荐指数
2
解决办法
3634
查看次数

从箭头表示法转换

我仍然试图弄清楚箭头表示法和Haskell中定义的箭头类型类的语义之间的相似之处.特别是,这个问题似乎有一个用箭头符号写的小计数器的非常规范的例子:

counter :: ArrowCircuit a => a Bool Int
counter = proc reset -> do
        rec     output <- returnA -< if reset then 0 else next
                next <- delay 0 -< output+1
        returnA -< output
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我如何在没有箭头符号的情况下将其转换回Haskell2010吗?

haskell arrows frp netwire

6
推荐指数
1
解决办法
333
查看次数

通过创建Comonad实例可以获得哪些好处

在我的应用程序中,我正在尝试实现一个动画系统.在此系统中,动画表示为循环帧列表:

data CyclicList a = CL a [a]
Run Code Online (Sandbox Code Playgroud)

我们可以(低效率)推进动画,如下所示:

advance :: CyclicList a -> CyclicList a
advance (CL x []) = CL x []
advance (CL x (z:zs)) = CL z (zs ++ [x])
Run Code Online (Sandbox Code Playgroud)

现在,我很确定这个数据类型是一个comonad:

instance Functor CyclicList where
  fmap f (CL x xs) = CL (f x) (map f xs)

cyclicFromList :: [a] -> CyclicList a
cyclicFromList [] = error "Cyclic list must have one element!"
cyclicFromList (x:xs) = CL x xs

cyclicLength :: CyclicList a -> Int
cyclicLength …
Run Code Online (Sandbox Code Playgroud)

haskell comonad

6
推荐指数
1
解决办法
293
查看次数

将静态库与clang链接,不依赖于顺序

在GCC中,我可以使用链接器标志-Wl,--start-group-Wl,--end-group解决与具有循环依赖关系的库的链接问题.我想对clang做同样的事情,但似乎这个功能在lld 3.2版本中删除了.我该怎么做?

c++ clang static-linking lld

6
推荐指数
1
解决办法
5963
查看次数

箭头对函数的优势

箭头比haskell中的常规函数​​有什么优势.他们可以做什么功能不能.函数可以使用fmap映射结构.

haskell arrows function

5
推荐指数
1
解决办法
266
查看次数

通过对Haskell中二进制函数的两个参数进行某些转换来"提升"哪个是最惯用的方法?

通过对Haskell中二进制函数的两个参数进行某些转换来"提升"哪个是最惯用的方法?让这个运算符命名为"lift",所以我希望它的类型是

lift :: (a -> b) -> (b -> b -> c) -> (a -> a -> c)
Run Code Online (Sandbox Code Playgroud)

一个天真的定义将是

lift t f = \x y -> f (t x) (t y)
Run Code Online (Sandbox Code Playgroud)

monads haskell functional-programming arrows applicative

5
推荐指数
1
解决办法
108
查看次数

与 Netwire 一起使用时对 ArrowLoop 的误解

在这篇文章中出色的答案的引导下,我试图获得一个ArrowLoop不使用箭头表示法的工作示例。在我完全理解箭头在幕后的工作原理之前,我对使用箭头表示法感到不舒服。话虽这么说,我已经构建了一个小程序,基于我对 Arrows 的(有限)理解应该可以工作。然而,它最终以可怕的异常终止<<loop>>

module Main where

import Control.Wire
import FRP.Netwire

farr :: SimpleWire (Int, Float) (String, Float)
farr = let
  fn :: Int -> Float -> ((String, Float), SimpleWire (Int, Float) (String, Float))
  fn i f = (("f+i: " ++ (show (fromIntegral i + f)), f + 0.1), loopFn)

  loopFn :: SimpleWire (Int, Float) (String, Float)
  loopFn = mkSFN $ \(i, f) -> fn i f
  in
   mkSFN $ \(i, _) -> fn i 0.0 …
Run Code Online (Sandbox Code Playgroud)

haskell arrows frp netwire

5
推荐指数
1
解决办法
311
查看次数