小编The*_*ora的帖子

左箭头<-在do块外是什么意思?

我最近遇到了以下代码,这让我很困扰

lowerSafeForeignCall dflags block
| (entry, middle, CmmForeignCall { .. }) <- blockSplit block
= do
 -- do block stuffs
 -- Block doesn't end in a safe foreign call:
| otherwise = return block
Run Code Online (Sandbox Code Playgroud)

这段代码来自 https://phabricator.haskell.org/rGHCb0534f78a73f972e279eed4447a5687bd6a8308e

在文件editor / cmm / CmmLayoutStack.hs中

983行

我真的很想知道第二行是什么<-。我相信lowerSafeForeignCall是一个函数,并且| 否则 ”表示此功能使用了防护功能。所以

(entry, middle, CmmForeignCall { .. }) <- blockSplit block
Run Code Online (Sandbox Code Playgroud)

必须是布尔类型。但是<-在任何do块之外。我在网上做了一些搜索,但仍然没有关于此用法的任何线索。

haskell ghc guard-clause pattern-guards

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

某人写下这样的foldlM定义需要什么知识或培训?

最近,我试图在我的一些实际案例制作系统中使用Haskell。Haskell类型系统确实为我提供了很大的帮助。例如,当我意识到我需要某种类型的功能时

f :: (Foldable t, Monad m) => ( a-> b -> m b) -> b -> t a -> m b
Run Code Online (Sandbox Code Playgroud)

实际上有类似的功能foldMfoldlMfoldrM

但是,真正令我震惊的是这些功能的定义,例如:

foldlM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
foldlM f z0 xs = foldr f' return xs z0
  where f' x k z = f z x >>= k
Run Code Online (Sandbox Code Playgroud)

因此函数f'必须为以下类型:

f' :: a -> b …
Run Code Online (Sandbox Code Playgroud)

haskell fold higher-order-functions

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

定义数据类型包括约束函数

我试图在一个简单的生产系统中采用ReaderT模式的想法。

在原始示例中,数据类型Env定义为:

data Env = Env
  { envLog :: !(String -> IO ())
  , ...
  }
Run Code Online (Sandbox Code Playgroud)

在我的实现中,我定义了一个类型类Serializable来帮助我记录不同的数据类型。这样我就可以拥有更通用的日志记录功能(包括不同文件格式的序列化):

data Env = Env
  { evnLog :: (Serializable a) => a -> FilePath -> IO ()
  , ...
  }
Run Code Online (Sandbox Code Playgroud)

当然,这是行不通的。错误消息是:

    Not in scope: type variable ‘a’
   |
61 |   { envLog :: (Serializable a) =>
   |                             ^
Run Code Online (Sandbox Code Playgroud)

如果a包含在的Type构造函数中Env,我将被迫不断地在ReaderT中更改Context信息,这确实很麻烦。

我只想将此通用函数传递给一系列计算,并在需要时使用它。

是否有可能不引入 aType的Type构造函数Env?也许ReaderT模式需要更多技巧来使用?

haskell

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

Option&lt;&amp;T&gt; 如何实现复制

我注意到 Option<&T> 和 Option<T> 的映射函数有些奇怪,经过快速谷歌搜索后,还有其他人注意到了同样的问题,如 这个问题中所述。我将仅使用相同的示例。

let greet: Option<String> = Some("hi".to_string());

let mapped = greet.map(|e|e);

dbg!(mapped);
dbg!(greet);
Run Code Online (Sandbox Code Playgroud)

错误消息是:

use of moved value: `greet` ....
Run Code Online (Sandbox Code Playgroud)

另一方面,下面的代码是可以的。

let greet: Option<String> = Some("hi".to_string());

let mapped = greet.as_ref().map(|e|e);

dbg!(mapped);
dbg!(greet);
Run Code Online (Sandbox Code Playgroud)

地图函数的类型是:

pub const fn map<U, F>(self, f: F) -> Option<U>
Run Code Online (Sandbox Code Playgroud)

因此,调用者的所有权应该转移到映射中的“self”,该问题的解释是“Option<&T>implements Copy”。

因此,Option<T> 转移所有权从而导致错误,而 Option<&T> 只是创建一个新副本。

但是,我找不到任何显示“Option<&T> Implements Copy”的地方,更糟糕的是,来自文档

/// The `Option` type. See [the module level documentation](self) for more.
#[derive(Copy, PartialOrd, Eq, Ord, Debug, Hash)]
#[rustc_diagnostic_item = "Option"] …
Run Code Online (Sandbox Code Playgroud)

ownership rust borrow-checker

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

使用Set.fromList,得到错误"Prelude.!!:index too large"

有一个清单 lc

*Main Lib MetaDefinition WHparseCSV WHparseTxT Set> :info lc
lc :: IO [Int]  -- Defined at <interactive>:2:5
*Main Lib MetaDefinition WHparseCSV WHparseTxT Set> length <$> lc
1704399
Run Code Online (Sandbox Code Playgroud)

我想知道这个列表的基数,所以我尝试通过执行以下操作将此列表转换为集合:

*Main Lib MetaDefinition WHparseCSV WHparseTxT Set> import Data.Set as Set
*Main Lib MetaDefinition WHparseCSV WHparseTxT Set> let sc = Set.fromList <$> lc 
Run Code Online (Sandbox Code Playgroud)

但是,当我试图计算基数时,我得到了错误:

*Main Lib MetaDefinition WHparseCSV WHparseTxT Set> length <$> sc
*** Exception: Prelude.!!: index too large
Run Code Online (Sandbox Code Playgroud)

类型sc是正确的:

*Main Lib MetaDefinition WHparseCSV WHparseTxT Set> :info sc
sc :: …
Run Code Online (Sandbox Code Playgroud)

haskell ghc

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