小编jam*_*idh的帖子

使用MultiParamTypeClasses时,是否需要在每个类函数中使用每种类型

当我使用MultiParamTypeClasses时,我可以创建忽略其中一个类型参数的类函数(即下面的"身份").

{-# LANGUAGE MultiParamTypeClasses #-}

data Add = Add
data Mul = Mul

class Test a b where
    identity::a

instance Test Int Add where
    identity = 0

instance Test Int Mul where
    identity = 1
Run Code Online (Sandbox Code Playgroud)

(这是一个精简版本,当然在完整的程序中会有其他功能使用"b").

示例编译,但我永远无法访问身份!

main = do
    putStrLn (show (identity::Int))
Run Code Online (Sandbox Code Playgroud)

导致"使用'身份'时没有(Test Int b0)的实例.

有没有办法获取身份?如果没有,编译器是否应该禁止我创建一个不使用所有类型参数的类函数?

haskell

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

由其各部分组成一个可存储的

我想把Foreign.Storable分成两部分......

import Foreign

data FullData type1 type2 = FullData {first::type1, second::type2}

instance (Storable type1, Storable type2)=>Storable (FullData type1 type2) where
    sizeOf _ = sizeOf (undefined::type1) + sizeOf (undefined::type2)
    alignment _ = 0 --I am just setting this to zero for testing....

main = putStrLn $ show $ sizeOf (undefined::FullData Int Char)
Run Code Online (Sandbox Code Playgroud)

然而,这失败了 -

storableTest.hs:13:44:
Could not deduce (Storable a1) arising from a use of `sizeOf'
from the context (Storable type1, Storable type2)
  bound by the instance declaration at storableTest.hs:12:10-74
The …
Run Code Online (Sandbox Code Playgroud)

haskell

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

对于这个,有什么比unsafePerformIO更好的东西吗?

到目前为止,我已经避免了需要unsafePerformIO,但今天可能需要改变....我想看看社区是否同意,或者是否有人有更好的解决方案.

我有一个库,需要使用存储在一堆文件中的一些配置数据.这些数据保证是静态的(在运行期间),但需要在无法编译Haskell程序的最终用户编辑的文件中(极少数情况下).(细节是不重要的,但将"/etc/mime.types"视为一个相当不错的近似值.它是一个在很多程序中使用的大型几乎静态的数据文件).

如果这不是一个库,我会使用IO monad ....但是因为它是一个在我的代码中被调用的库,它实际上迫使IO monad冒出几乎所有我写的多个模块!虽然我需要一次性读取数据文件,但这种低级别调用有效的纯粹,所以这是一个非常不可接受的结果.

仅供参考,我计划将调用包装在unsafeInterleaveIO中,以便只加载所需的文件.我的代码看起来像这样....

dataDir="<path to files>"

datafiles::[FilePath]
datafiles = 
  unsafePerformIO $
  unsafeInterleaveIO $
  map (dataDir </>) 
  <$> filter (not . ("." `isPrefixOf`))
  <$> getDirectoryContents dataDir

fileData::[String]
fileData = unsafePerformIO $ unsafeInterleaveIO $ sequence $ readFile <$> datafiles
Run Code Online (Sandbox Code Playgroud)

鉴于读取的数据是引用透明的,我很确定unsafePerformIO是安全的(这已在很多地方讨论过,例如" 使用unsafePerformIO合适吗? ").不过,如果有更好的方法,我很乐意听到它.


最新情况:

回应Anupam的评论......

有两个原因导致我无法将lib分解为IO和非IO部分.

首先,数据量很大,我不想一次将其全部读入内存.请记住,IO总是严格读取....这就是我需要进行unsafeInterleaveIO调用以使其变得懒惰的原因.恕我直言,一旦你使用unsafeInterleaveIO,你也可以使用unsafePerformIO,因为风险已经存在.

其次,打破IO特定部分只是替代IO monad的冒泡和IO读取代码的冒泡,以及传递数据(我可能实际上选择使用状态monad传递数据无论如何,所以将IO monad替换为各州的monad并不是一个改进.如果低级函数本身不是纯粹的,那就不会那么糟糕了(想想我上面的/etc/mime.types示例,想象一下Haskell extensionToMimeType函数,它本质上是纯粹的,但需要获取数据库来自文件的数据......突然,堆栈中从低到高的所有内容都需要调用或通过a readMimeData::IO String.为什么每个人main甚至需要关心多层深度子模块的库选择?).

haskell

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

Cabal 有默认目标吗?

如果我的 .cabal 文件有多个可执行文件,我可以通过键入名称挑选出一个来构建

cabal build myExecutable
Run Code Online (Sandbox Code Playgroud)

但我很懒,只想打字

cabal build
Run Code Online (Sandbox Code Playgroud)

对于默认目标(我可以忍受为辅助可执行文件输入额外的字符)。

这可能吗?(我一直在谷歌搜索并浏览阴谋集团手册一段时间了......还没有明确的答案)。

我必须这样做,例如,每天 1000 次....

haskell cabal

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

如何更改runTCPClient超时持续时间?

问题说明了一切....我正在使用Data.Conduit.Network,有时服务器没有启动.默认超时需要几分钟,我的程序需要在几秒钟内知道.

{-# LANGUAGE OverloadedStrings #-}

import Data.Conduit.Network

main = do --use any IP address that isn't up....  I use 1.2.3.4 for testing
  runTCPClient (clientSettings 80 "1.2.3.4") $ \server -> do
    putStrLn "connected"
Run Code Online (Sandbox Code Playgroud)

我在文档和来源中上下打量,答案对我来说并不清楚.我想这可能是不可能的......


回复@haoformayor答案的其他信息....

我最终使用了@haoformayor建议的类似方法,但需要进行一些更改才能使其正常工作.这是我目前的工作代码.

runTCPClientWithConnectTimeout::ClientSettings->Double->(AppData->IO ())->IO ()
runTCPClientWithConnectTimeout settings secs cont = do
  race <- newChan
  resultMVar <- newEmptyMVar

  timerThreadID <- forkIO $ do
    threadDelaySeconds secs
    writeChan race False

  clientThreadID <- forkIO $ do
    result <-
      try $
      runTCPClient settings $ \appData -> do
        writeChan race True …
Run Code Online (Sandbox Code Playgroud)

haskell

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

作家Monad现在适合大型懒惰列表吗?

我已经在多个地方读过列表的编写器monad将该完整列表保存在内存中,因此不应该用于除小样本之外的任何其他内容(例如,不记录日志).

例如,请阅读此处

但是,为了测试声明,我编写了以下程序,并且实际上表明它成功地输出了一个懒惰的无限列表!

import Control.Monad.Writer

createInfiniteList :: Int -> Writer [Int] ()
createInfiniteList i = do
  tell [i]
  createInfiniteList (i+1)

main :: IO ()
main = do
  let x = execWriter $ createInfiniteList 1
  print x
Run Code Online (Sandbox Code Playgroud)

我看过这个程序输出超过10亿个项目(它运行得非常快),并且监视我的机器上的内存使用率从未超过0.1%.

作家monad是否已被重写以修复原始问题?我可以指望它将来继续以这种方式工作吗?

注意 - 我知道存在更好的日志记录monad(我在其他地方使用它们)...我想要的用例不是日志记录(但它是类似的)

haskell

5
推荐指数
0
解决办法
124
查看次数

我可以在特定文件中有选择地删除.cabal文件的`ghc-options`吗?

我在用

ghc-options: -Wall
Run Code Online (Sandbox Code Playgroud)

在我的.cabal文件中,并且喜欢它....

....除非我讨厌它.例如,我有一个Constants.hs看起来像这样的文件

numDogs=1000
numCats=2000
......
....etc for like 100 lines
Run Code Online (Sandbox Code Playgroud)

....当然-Wall抱怨我不提供所有类型的签名,而是将文件更改为此

numDogs::Int
numDogs=1000

numCats::Int
numCats=2000

....etc
Run Code Online (Sandbox Code Playgroud)

真的会很愚蠢.

那么,有没有办法在每个文件的基础上关闭ghc-opts.

(我知道我可以从cabal中省略ghc-options,并把它放在我想要它使用的每个文件中{-# OPTIONS_GHC -Wall #-},但是当我这样做时,我经常忘记文件,所以我宁愿不这样做办法)

haskell

3
推荐指数
2
解决办法
204
查看次数

Haskell中可调整大小的IO数组

ArrayRef 似乎是提供可调整大小的IO阵列的软件包,但....

ArrayRef 似乎已经过时了(它甚至不会用新的GHC编译).

有谁知道在GHC/Haskell中创建可调整大小的数组的现代方法?我最终可能会采用相关的东西(如序列),但如果可能的话,我希望坚持使用持续时间读取/修改的东西.

haskell

3
推荐指数
1
解决办法
177
查看次数

安全记录字段查询

有没有一种干净的方法来避免以下样板:

给定一个记录数据类型定义...。

data Value = A{ name::String } | B{ name::String } | C{}
Run Code Online (Sandbox Code Playgroud)

编写安全返回的函数 name

getName :: Value -> Maybe String
getName A{ name=x } = Just x
getName B{ name=x } = Just x
getName C{} = Nothing
Run Code Online (Sandbox Code Playgroud)

我知道您可以使用Template Haskell做到这一点,我正在寻找一种比这更清洁的解决方案,也许是GHC扩展或其他我忽略的东西。

haskell

2
推荐指数
1
解决办法
155
查看次数

输入'< - '上的解析错误:Haskell

我正在从用户那里获取输入,代码如下:

putStrLn $ "Enter number"
num <- getLine
main = print $ num
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,编译器会出现以下错误:

ra.hs:10:5: parse error on input `<-'
Run Code Online (Sandbox Code Playgroud)

如何删除此错误?我试图使用空格,以及制表符,但错误仍然存​​在.请帮忙.

haskell parse-error

0
推荐指数
1
解决办法
152
查看次数

标签 统计

haskell ×10

cabal ×1

parse-error ×1