我偶尔会看到有人说QuickCheck中的Gen类型不遵守monad法则,尽管我没有看到很多解释.现在,QuickCheck 2.7的Test.QuickCheck.Gen.Unsafe模块说Gen只是"道德上"的monad,但简短的解释让我挠头.你能否一步一步地说明Gen如何违反monad法律?
在类型签名上写上下文时,通常我会做类似的事情
f :: (Enum a, Ord a) => a -> a
Run Code Online (Sandbox Code Playgroud)
但是,通过纯粹的愚蠢运气,我发现这个编译并且似乎工作相同,至少在GHC 7.8:
f :: Enum a => Ord a => a -> a
Run Code Online (Sandbox Code Playgroud)
两者之间的理论或实际差异是什么?第二个不太正统吗?该哈斯克尔报告似乎没有提及第二种形式的,我从来没有见过任何地方使用. 相关问题.
为什么我们需要Control.Lens.Reified?有什么理由我不能Lens直接放入容器吗?reify无论如何,意味着什么?
假设我有libfoo.这取决于libbar.根据包版本控制策略,我指定
libbar ==0.1.*
Run Code Online (Sandbox Code Playgroud)
在Build-depends中:在我的cabal文件中.
然后libbar的开发者发布了一个新版本0.2.我测试它并没有影响libfoo的更改.所以我改变了我的Build-depends to
libbar ==0.2.*
Run Code Online (Sandbox Code Playgroud)
或者也许是
libbar >= 0.1 && < 0.3
Run Code Online (Sandbox Code Playgroud)
虽然我可以想到不以后一种方式去做的理由.这是我对libfoo 的唯一改变.
libfoo导出接受libbar中定义的类型和libbar中定义的返回类型的函数.但是,对libbar的更改不会影响任何这些功能.
libfoo的第一个版本是0.1.0.0.libfoo的第二个版本应该有什么版本号?
在哈斯克尔你可以说
main = do
let x = 5
print x
Run Code Online (Sandbox Code Playgroud)
这将无法编译:
main = do
let x = 5
in print x
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用显式布局,则不会编译:
main = do {
let x = 5;
print x;
}
Run Code Online (Sandbox Code Playgroud)
但这有效:
main = do {
let x = 5
in print x;
}
Run Code Online (Sandbox Code Playgroud)
我对吗?有没有什么地方我可以阅读更多关于显式布局和做和让符号? Haskell 98报告的第3.14节似乎在我看来我的第三个例子应该有用,因为它说我可以写
do { let DECLS; stmts }
Run Code Online (Sandbox Code Playgroud)
它转化为
let DECLS in do { stmts }
Run Code Online (Sandbox Code Playgroud) 根据Common Lisp HyperSpec (CLHS),mapcan用于nconc将其结果合并到一个列表中。CLHS 还表示
(mapcon f x1 ... xn)
== (apply #'nconc (maplist f x1 ... xn))
Run Code Online (Sandbox Code Playgroud)
所以我一直担心使用applywhere call-arguments-limitis low 的后果 - CLHS 说它可以低至 50,而在 LispWorks 上它是 2047。在 LispWorks 上,
(mapcan #'list (loop for i from 0 to call-arguments-limit collect i))
成功,同时
(apply #'nconc (mapcar #'list (loop for i from 0 to call-arguments-limit collect i)))
失败了。如果mapcan真的必须使用nconc,这两个不都应该失败吗?
Data.ByteString.hGetContents的文档说
与hGet一样,文件中的字符串表示形式假定为ISO-8859-1.
为什么它必须"假设"任何关于"文件中的字符串表示"的内容?数据不一定是字符串或编码文本.如果我想要处理编码文本,我会使用Data.Text或者Data.ByteString.Char8.我认为ByteString的重点是数据是作为8位字节的列表处理的,而不是文本字符.假设ISO-8859-1的影响是什么?
假设我Proxy在 Haskell Pipes 中有两个。它们代表外部系统进程。
produce :: MonadIO m => Producer ByteString m ExitCode
consume :: MonadIO m => Consumer ByteString m ExitCode
Run Code Online (Sandbox Code Playgroud)
所以我把它们挂在一个Effect,像这样:
effect :: Effect m ExitCode
effect = produce >-> consume
Run Code Online (Sandbox Code Playgroud)
这将从终止的第一个Effect开始给我。通常,这将是,而不是。即使它没有首先终止,获得返回值的惯用 Pipes 方法是什么?ExitCodeProxyproduceconsumeconsume
到目前为止,我认为如果不进行某种令人讨厌的带内信令,这是不可能的,因此consume知道流已完成。最后一个代理知道关闭的唯一方法是从 中获取一些东西await,所以我可以向它发送一个空ByteString的信号来表示流已完成。只是感觉不太对劲。我现在拥有的是一个单独的 MVar,它可以提供退出值,但我认为必须有一种更惯用的方法来做到这一点。
我刚刚开始学习类型系列.GHC文档指出顶级和相关类型系列具有相同的功能,但我写的代码在顶层的行为与家族关联时的行为不同.这编译并运行良好:
{-# LANGUAGE TypeFamilies #-}
module Test where
-- type family R a
-- type instance R Maybe = Int
class C' a where
type R a
getInt' :: a Int
getBool' :: R a -> a Bool
instance C' Maybe where
type R Maybe = Int
getInt' = Just 3
getBool' i = Just $ i < 10
printer :: IO ()
printer = print $ (getBool' 5 :: Maybe Bool)
Run Code Online (Sandbox Code Playgroud)
但这给了我一个类型错误:
{-# LANGUAGE TypeFamilies #-}
module Test where …Run Code Online (Sandbox Code Playgroud)