我有一个非常简单的片段:
\n{-# LANGUAGE LinearTypes #-}\n\nmodule Lib where\n\ndata Peer st = Peer { data :: String } deriving Show\n\ndata Idle\ndata Busy\n\nsendToPeer :: Peer Idle %1-> Int -> IO (Peer Busy)\nsendToPeer c n = case c of Peer d -> pure $ Peer d\nRun Code Online (Sandbox Code Playgroud)\n我在resolver: ghc-9.0.1.
从文档中:
\n\n\n函数 f 是线性的,如果:当其结果仅被消耗一次时,\n则其参数仅被消耗一次。直观上,这意味着在 f 定义的每个分支中,其参数 x 必须仅使用一次。可以通过以下方式完成
\n\n
\n- 返回未修改的 x
\n- 将 x 传递给线性函数
\n- 对 x 进行模式匹配并以相同的方式仅使用每个参数一次。
\n- 将其作为函数调用并以相同的方式仅使用一次结果。
\n
我的函数sendToPeer …
我读这个,我觉得这样的:
措施 -为了使Haskell函数出现在细化类型中,我们需要将其提升到细化类型级别。
还有其他一些文件声称需要采取措施在合同中使用这种功能。但是我尝试了这个:
{-@ len :: List a -> Nat @-}
len :: List a -> Int
len Nil = 0
len (x `Cons` xs) = 1 + len xs
{-@ mymap :: (a -> b) -> xs : List a -> { ys : List b | len xs == len ys } @-}
mymap :: (a -> b) -> List a -> List b
mymap _ Nil = Nil
mymap f (x `Cons` …Run Code Online (Sandbox Code Playgroud) 为什么此功能总是成功?它始终True以任何值和任何类型返回。这是正确的行为吗?
f a b = case a of b -> True; _ -> False
Run Code Online (Sandbox Code Playgroud) 我正在尝试解决LiquidHaskell 教程中的一些练习。所以,我这样写:
data List a = Nil | Cons a (List a) deriving (Show)
infixr 5 `Cons`
{-@ len :: List a -> Nat @-}
len :: List a -> Int
len Nil = 0
len (x `Cons` xs) = 1 + len xs
{-@ mymap :: (a -> b) -> xs : List a -> { ys : List b | len xs == len ys } @-}
mymap :: (a -> b) -> List a -> List …Run Code Online (Sandbox Code Playgroud) 我发现了有趣的 C# 库。而且代码中有一个奇怪的语法,我不明白。这样的语法意味着什么:
IRequestHandler<,>
Run Code Online (Sandbox Code Playgroud)
?是一样的IRequestHAndler<T1, T2>还是别的什么?
当我编写一些可能失败的函数时:
somefun :: (Monad m, ...) -> ... -> m a
somefun ... =
...
fail "some error"
Run Code Online (Sandbox Code Playgroud)
我可以fail用来失败。但我也可以重写这个函数来使用MonadThrow,所以:
somefun :: (MonadThrow m, ...) -> ... -> m a
somefun ... =
...
throwM "Some error"
Run Code Online (Sandbox Code Playgroud)
所以,今天我们得到了MonadFail,我们也得到Monad了fail,从另一个角度来看,我可以失败throwM。在 LTS-11.7 中编写此类函数的正确方法是什么?throwMvs.的好处是什么fail(因为有些库使用一种方法和另一种方法 - 使用其他方法)?
编辑:另外,当我看到这个时我无法理解 - 这是临时的解决方法,但在未来的版本fail中将完全从Monad?
我看到这里
-- Note that "forever" isn't necessarily non-terminating.
-- If the action is in a @'MonadPlus'@ and short-circuits after some number of iterations.
-- then @'forever'@ actually returns `mzero`, effectively short-circuiting its caller.
Run Code Online (Sandbox Code Playgroud)
说实话,我不太明白这个注释。他们是否意味着可以打破forever,MonadPlus例如 - IO Bool?就说吧,IO False会打破它...
从某一方面来说IO也是MonadPlus如此。也许我必须用其他东西包裹我才能实现与andIO Bool决裂的可能性?这条注释到底是什么意思?foreverIO BoolMonadPlus
当然,我可以例外地打破它或实现自己的,forever但我的兴趣在于这个奇怪的注释。
不同的操作系统有不同的并发子系统,有操作系统进程、POSIX 线程,现在 Linux 中还有“LWP”线程,Windows 有进程、纤程、线程等。每个进程都由操作系统调度程序进行调度,并获得自己的 CPU 时间量。对于 Linux“LWP”来说确实如此,因为它们是进程但共享内存空间,而对于用户空间线程则不然,其中所有线程共享一个 CPU 时间量。
Haskell 有 forkIO。我在 Haskell 源代码中找到了下一个评论:
Haskell 线程的调度是在 Haskell 运行时系统内部完成的,并且不使用任何操作系统提供的线程包。
还
在性能方面,“forkOS”(又名绑定)线程比“forkIO”(又名未绑定)线程昂贵得多,因为“forkOS”线程绑定到特定操作系统线程,而“forkIO”线程可以运行由任何操作系统线程。“forkOS”线程和“forkIO”线程之间的上下文切换比两个“forkIO”线程之间的上下文切换要昂贵很多倍。
它强调创建的线程forkIO不是由操作系统调度程序调度的。据我了解,它们可以免受常见阻塞(当然可以-thread选择),但在这种情况下,我有 3 个悬而未决的问题:
forkOS比使用更好,对吗forkIO?我的意思是,如果我有 2 个线程,其中一个线程提供 HTTP 服务,另一个线程进行大量磁盘 I/O 操作,那么更好的解决方案是使用forkOS比forkIO?我找到了一种在Windows 10中异步运行命令的方法,现在我尝试通过其标准输入、标准输出与其进行通信。我是通过 Python 完成的 - 我运行了 python.exe 进程,向其发送了一个类似“print(1+9)”的字符串,并得到了结果 - “10”。所以,现在我尝试在 Pharo 或 Squeak 中重复这个简单的任务:
p := WindowsProcess command: 'c:\python38\python.exe'.
a := p accessor.
in := a getStdIn.
out := a getStdOut.
inHnd := a getStdInHandle.
outHnd := a getStdOutHandle.
Run Code Online (Sandbox Code Playgroud)
那么,下一个问题是 - 如何处理in, out, inHnd, outHnd?我的感觉是,我可以从它们读取/写入,但我得到的例外是in,inHnd-它们是ByteArray,所以无法调用类似的东西nextPutAll:或next:对它们进行调用。如何与这个进程进行通信?
我有一个价值观:
my :: [(A, Either B [C])]
Run Code Online (Sandbox Code Playgroud)
我想[(A, C)]用镜头从中得到。结果项是来自my以下项的项:
Right [C]Right [C]至少有 1 个项目,因此结果从中获取第一个(头)项目我知道如何获得 ,[C]但我不知道如何获得[(A, C)]。
haskell ×8
c# ×1
concurrency ×1
haskell-lens ×1
linear-types ×1
pharo ×1
smalltalk ×1
squeak ×1
stdin ×1
stdout ×1