小编dfl*_*str的帖子

查看Template Haskell生成的代码的首选方法

如您所知,Template Haskell用于在编译时以编程方式生成各种AST拼接.

然而,拼接通常可能非常不透明,并且通常难以辨别拼接实际生成的内容.如果你运行Qmonad进行拼接,并且拼接是良好类型的,你可以很好地show表示生成的AST片段,但由于其非结构化布局,这种表示很难理解.

将TH生成的AST转换为类似于普通Haskell代码的首选方法是什么,以便可以轻松读取和理解代码?可以从例如给定Dec值重建源代码吗?是否必须阅读GHC核心代码?有没有办法至少构建AST,使其变得更具可读性(超出pretty-show包裹的范围)?

haskell pretty-print ghc template-haskell

40
推荐指数
2
解决办法
3130
查看次数

使用镜头有哪些优缺点?

镜头似乎没有任何缺点,同时具有优于标准Haskell的显着优势:是否有任何理由我不应该尽可能使用镜头?有性能考虑吗?另外,模板Haskell是否有任何重大开销?

haskell lenses

25
推荐指数
2
解决办法
3259
查看次数

Monad变压器用于进度跟踪

我正在寻找一个可用于跟踪程序进度的monad变换器.要解释如何使用它,请考虑以下代码:

procedure :: ProgressT IO ()
procedure = task "Print some lines" 3 $ do
  liftIO $ putStrLn "line1"
  step
  task "Print a complicated line" 2 $ do
    liftIO $ putStr "li"
    step
    liftIO $ putStrLn "ne2"
  step
  liftIO $ putStrLn "line3"

-- Wraps an action in a task
task :: Monad m
     => String        -- Name of task
     -> Int           -- Number of steps to complete task
     -> ProgressT m a -- Action performing the task
     -> ProgressT m …
Run Code Online (Sandbox Code Playgroud)

monads haskell functional-programming coroutine monad-transformers

17
推荐指数
1
解决办法
906
查看次数

"交错同态"的概念是真实的吗?

我需要以下类功能:

class InterleavedHomomorphic x where
  interleaveHomomorphism :: (forall a . f a -> g a) -> x f -> x g
Run Code Online (Sandbox Code Playgroud)

显然,我为它发明的名称绝不是任何东西的官方术语,上面的类型不是很优雅.这是一个在某些库中有名称甚至实现的概念吗?有没有更合理的方法呢?


这个函数的目的是我有一些f注释一些数据的上下文(为了这个问题Foo,Bar它只是随机的示例数据结构):

data Foo f = One (f (Bar f)) | Product (f (Foo f)) (f (Foo f))
data Bar f = Zero | Succ (f (Bar f))
Run Code Online (Sandbox Code Playgroud)

我想以多态方式转换数据的上下文; 只知道上下文之间的同态,而不是(必然)关心数据本身.这可以通过提供instance InterleavedHomomorphic Fooinstance InterleavedHomomorphic Bar在上面的例子中完成.

haskell functor category-theory comonad homomorphism

14
推荐指数
1
解决办法
816
查看次数

"Monad-friendly"基于事件的IO

我想使用" epoll"式事件管理实现高效的单线程套接字通信.

如果我"从头开始"编写一个非常强制性的程序,我会基本上这样做(只是一些我刚输入的伪代码 - 可能不会编译):

import Control.Concurrent

import Data.ByteString (ByteString)
import qualified Data.ByteString as ByteString

import qualified GHC.Event as Event

import Network
import Network.Socket
import Network.Socket.ByteString

main = withSocketFromSomewhere $ \ socket -> do
  let fd = fromIntegral . fdSocket $ socket

  -- Some app logic
  state <- newMVar "Bla"

  -- Event manager
  manager <- Event.new

  -- Do an initial write
  initialWrite socket state manager

  -- Manager does its thing
  Event.loop manager

write manager socket bs =
  -- Should …
Run Code Online (Sandbox Code Playgroud)

sockets concurrency events haskell

11
推荐指数
1
解决办法
1536
查看次数

甚至更广义的新型派生

在某些类上下文中使用时,Newtypes通常用于更改某些类型的行为.例如,可以使用Data.Monoid.All包装器来更改Bool用作a时的行为Monoid.

我目前正在编写一个适用于各种不同类型的newtype包装器.包装器应该改变一个特定类实例的行为.它可能看起来像这样:

newtype Wrapper a = Wrapper a

instance Special a => Special (Wrapper a) where
  -- ...
Run Code Online (Sandbox Code Playgroud)

但是,添加此包装器通常会改变包装类型的可用性.例如,如果我以前能够使用该函数mconcat :: Monoid a => [a] -> a,我现在无法将其用于包装值列表.

我当然可以使用-XGeneralizedNewtypeDerivingnewtype Wrapper a = Wrapper a deriving (Monoid).然而,这只能解决问题,Monoid而不是其他类,而我将处理一个充满不同类的开放世界,并且独立的孤立广义newtype派生并不是真正的实用选择.理想情况下,我想写deriving hiding (Special)(除了派生每个类Special),但当然这不是有效的Haskell.

有没有办法做到这一点,或者我只是搞砸了,需要添加GHC功能请求?

haskell typeclass ghc newtype

9
推荐指数
1
解决办法
1216
查看次数

通过蓝牙/ RFCOMM/SPP发送二进制数据会将0x0A转换为0x0D 0x0A

我通过以下命令在Linux上运行蓝牙RFCOMM服务:

sdptool add --channel 1 SP
rfcomm watch hci0 1 "$COMMAND" {}
# ^ here
Run Code Online (Sandbox Code Playgroud)

$COMMAND将二进制数据写入作为参数传递的文件.我通过执行以下操作测试了它的行为:

FIFO=$(tempfile)
mkfifo "$FIFO"
"$COMMAND" "$FIFO" &
cat "$FIFO" | hexdump -C # <- output is correct
Run Code Online (Sandbox Code Playgroud)

然而,通过SPP/RFCOMM发现(UUID从不同的装置连接到服务时00001101-0000-1000-8000-00805F9B34FB),我看到的每个实例0x0A(LF)被替换为0x0D 0x0A(CR LF)中的流.问题不在接收端,因为我尝试连接到也发送二进制数据的硬件串行设备,并且转换不会发生.它必须是# ^ here执行替换的第一个片段(在行上方)中的命令.

为什么该rfcomm工具会进行此替换,如何禁用它?

linux newline serial-port bluetooth

9
推荐指数
1
解决办法
6403
查看次数

约束子集高阶约束

使用这种GHC.Exts.Constraint类型,我有一个广义的存在量化数据结构,如下所示:

data Some :: (* -> Constraint) -> * where
  Specimen :: c a => a -> Some c
Run Code Online (Sandbox Code Playgroud)

(实际上,我的类型比这更复杂;这只是一个简化的例子)

现在,让我们说我有一个函数,例如,需要Enum约束,我想要对其进行操作Some c.我需要做的是检查Enum约束是否暗示c:

succSome :: Enum ? c => Some c -> Some c
succSome (Specimen a) = Specimen $ succ a
Run Code Online (Sandbox Code Playgroud)

?在这种情况下,我如何实现运算符?可能吗?

haskell existential-type ghc type-constraints higher-rank-types

9
推荐指数
1
解决办法
274
查看次数

JPA级联持久化与实体ElementCollection键

我有两个这样的JPA实体:

@Entity
class Foo {
    @Id
    private long id;
    // ...
}

@Entity
class Bar {
    @ElementCollection(targetClass = String.class, fetch = FetchType.LAZY)
    @MapKeyJoinColumn(name = "foo_id", referencedColumnName = "id")
    @MapKeyClass(Foo.class)
    @Column(name = "content")
    @CollectionTable(name = "bar_foo_content",
                     joinColumns = @JoinColumn(name = "bar_id", referencedColumnName = "id"))
    @ManyToMany(cascade = CascadeType.ALL)
    private Map<Foo, String> fooContent = Maps.newHashMap();
    // ...
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,该fooContent字段在Bar和之间形成了多对多关系Foo,因此我认为使用@ManyToMany该字段指定级联是合适的.但是,当尝试在地图中保留一个Bar带有几个Foo ? String值的时候,我得到以下异常:

javax.persistence.RollbackException: java.lang.IllegalStateException: During synchronization a new object was found through …
Run Code Online (Sandbox Code Playgroud)

java jpa eclipselink

8
推荐指数
2
解决办法
9143
查看次数

具有部分原子性的STM用于某些TVars

我正在使用STM做事,除此之外还使用了TBQueue数据结构并取得了巨大的成功.我一直在使用它的一个有用功能包括根据a中的前提条件从中读取TVar,基本上是这样的:

shouldRead <- readTVar shouldReadVar
if shouldRead
  then do
    a <- readTBQueue queue
    doSomethingWith a
  else doSomethingElse
Run Code Online (Sandbox Code Playgroud)

如果我们假设在执行此块之前它queue是空的并且shouldReadVar包含True它,那么它将导致readTBQueue调用retry,并且当shouldReadVar包含Falsequeue包含元素时,块将被重新执行,无论先发生什么.


我现在需要一个同步通道数据结构,类似于本文中描述的结构(如果你想理解这个问题,请阅读它),除非它需要在前一个例子中的前置条件下可读,也可能与其他东西一起构成.

让我们SyncChan用它来定义这个数据结构writeSyncChanreadSyncChan定义操作.

这是一个可能的用例:这个(伪)代码(因为我混合了STM/IO概念,所以不会起作用):

shouldRead <- readTVar shouldReadVar
if shouldRead
  then do
    a <- readSyncChan syncChan
    doSomethingWith a
  else doSomethingElse
Run Code Online (Sandbox Code Playgroud)

假设当前没有其他线程在writeSyncChan调用上阻塞,并且shouldReadChan包含True,我希望块" retry"直到shouldReadChan包含False,或者在a上包含不同的线程块 …

synchronization haskell transactions ghc stm

7
推荐指数
1
解决办法
185
查看次数