有没有更惯用的方式来表达如下内容?
fn main() {
let mut foo: Option<u8> = None;
match foo {
Some(foo_val) if ! (foo_val < 5) /* i.e. the negation of my acceptance condition */ => {}
_ => { foo.replace(5); }
}
}
Run Code Online (Sandbox Code Playgroud)
似乎大多数时候都有一种替代方案可以替代一只不做任何事情的手臂,但我一直无法找到适合这种特殊情况的替代方案。
我想说的是更直接的if foo.is_none() || /* some way to extract and test the inner value */ { ... },或者也许是一些我无法理解的链接技巧。
neovim API提供了nvim_set_current_dir(),但显然没有公开查询的方法cwd。我该怎么做呢?
在 Rust 中,我们可以说例如
if Some(inner_val) = option { ... }
Run Code Online (Sandbox Code Playgroud)
Haskell 有等效的吗?
我将提供一些背景信息,以防这看起来像是一件愚蠢的事情(请随意告诉我这是一件愚蠢的事情)。我一边阅读管道自述文件一边做练习。其中之一指示读者“实现一个查看函数,从上游获取下一个值(如果可用),然后将其放回流中。” 我这样做如下:
peek :: Monad m => ConduitT a o m (Maybe a)
peek = do
mx <- await
case mx of
Nothing -> return mx
Just x -> do
leftover x
return mx
Run Code Online (Sandbox Code Playgroud)
我不喜欢我必须return mx用双臂说这句话。人们很容易想象这样的情况:手臂之间分担的工作比简单的工作要多得多return。我想要一种方法来有条件地完成不共享的工作,然后继续前进。我可以说
peek2 :: Monad m => ConduitT a o m (Maybe a)
peek2 = do
mx <- await
when
(isJust mx)
( do
let Just x = …Run Code Online (Sandbox Code Playgroud) 想象一下我有一个对象,它是一个类的实例,如下所示:
@dataclass
class Foo:
bar: int
baz: str
Run Code Online (Sandbox Code Playgroud)
我使用它是dataclasses为了方便,但在这个问题的上下文中,不要求该类是dataclass.
通常,如果我想解压此类对象的属性,我必须实现__iter__,例如如下:
class Foo:
...
def __iter__(self) -> Iterator[Any]:
return iter(dataclasses.astuple(self))
bar, baz = Foo(1, "qux")
Run Code Online (Sandbox Code Playgroud)
然而,从像Pyright这样的静态类型检查器的角度来看,我现在丢失了bar和的任何类型信息baz,它只能推断出它们的类型Any。我可以通过iter手动创建元组参数来稍微改进:
def __iter__(self) -> Iterator[Union[str, int]]:
return iter((self.bar, self.baz))
Run Code Online (Sandbox Code Playgroud)
但我仍然没有bar和的特定类型baz。我可以注释bar然后直接baz使用,dataclasses.astuple如下:
bar: str
baz: int
bar, baz = dataclasses.astuple(Foo(1, "qux"))
Run Code Online (Sandbox Code Playgroud)
但这需要可读性较差的多级列表理解,例如
bars: list[int] = [
bar for bar, _ in [dataclasses.astuple(foo) for …Run Code Online (Sandbox Code Playgroud) 我刚刚开始使用 TypeScript,遇到了一些令人困惑的行为。如果我有一个interface MyInterface具有多个属性的 和 a key: keyof MyInterface,我可以使用属性的任意值创建接口的新实例key。考虑以下:
interface Values {
one: 1;
two: 2;
}
function getNewVals(vals: Values, key: keyof Values): Values {
// aValue: 1 | 2, so clearly typescript knows the union of possible values
const aValue = vals[key];
// but this is not an error
return { ...vals, [key]: "foo" };
// I can do this, too
const another: Values = { one: 1, two: 2, [key]: "foo" };
// however, …Run Code Online (Sandbox Code Playgroud) 我开始熟练地使用 Haskell 编写代码,并且我注意到我已经犯过几次的错误模式:
doFoo :: ...
doFoo pattern1 = fooHelper ...
doFoo pattern2 = fooHelper ...
where
fooHelper = ...
Run Code Online (Sandbox Code Playgroud)
fooHelper当然不在范围之内doFoo pattern1。我发现自己通过使用单个无可辩驳的模式来纠正错误doFoo,然后使用函数内的 case 表达式对其进行模式匹配:
doFoo :: ...
doFoo irrefutable = case irrefutable of
pattern1 -> fooHelper ...
pattern2 -> fooHelper ...
where
fooHelper = ...
Run Code Online (Sandbox Code Playgroud)
fooHelper现在当然在这两种模式的范围内。
据我所知,函数级别的模式匹配在各个方面都等同于 case 表达式中的模式匹配(如果我错了,请纠正我),所以这似乎是一个合理的做法。这种模式是否被认为是惯用的,或者是否有更好的(或只是常用的替代方案)方法?
当 VS Code 从“活动”(即通过 UI)启动时,我收到一条错误消息“无法解析您的 shell 环境:生成的 shell 出现意外的退出代码(代码 1,信号为 null)”。发生这种情况是因为我的 rc 文件(zsh,这里不重要)中的最后一个块是:
if command -v tmux &> /dev/null \
&& [ -n "$PS1" ] \
&& [[ ! "$TERM" =~ screen ]] \
&& [[ ! "$TERM" =~ tmux ]] \
&& [ -z "$TMUX" ] \
&& [[ "$TERM_PROGRAM" != "vscode" ]]; then
exec tmux
fi
Run Code Online (Sandbox Code Playgroud)
我在这里得到了守卫的 tmux 特定部分,在这里得到了代码特定部分。但是,当代码运行此处描述的“运行(或‘解析’)shell 环境的小进程”时,$TERM_PROGRAM似乎并未设置,因此exec tmux仍然运行,因此出现错误。
如何检测环境解析器正在运行?它是否设置了我可以测试的任何其他变量?
编辑:我意识到我可以将环境列出到我的 rc 中的文件中,并且我发现了许多前缀为 的变量VSCODE_,即以下内容: …
我正在按照这个答案来学习如何在Sequences 上进行模式匹配。具体而言,假设我正在使用 a 作为队列在二维网格上实现广度优先搜索Sequence。仅使用ViewPatterns,我可能会想出如下内容:
{-# LANGUAGE ViewPatterns #-}\n\nimport qualified Data.Sequence as Seq\nimport qualified Data.Set as Set\n\nbfs :: Seq.Seq ((Int, Int), Int) -> Set.Set (Int, Int) -> Int\nbfs (Seq.viewr -> Seq.EmptyR) _ = -1 -- goal not found\nbfs (Seq.viewr -> (coords Seq.:> (coord@(r, c), dist))) seen = -- search plumbing...\nRun Code Online (Sandbox Code Playgroud)\n根据@Cactus\'s 的回答,如果我也想使用PatternSynonyms,我想出:
{-# LANGUAGE PatternSynonyms #-}\n\n...\n\npattern Empty :: Seq.Seq a\npattern Empty <- (Seq.viewr -> Seq.EmptyR)\n\npattern …Run Code Online (Sandbox Code Playgroud) 我有一个<input>标签type="number",我想禁用键盘输入,以强制用户使用微调器(向上和向下箭头)更改值。我在每次更改时都会消耗输入值,因此我想这样做,这样我就不必实时验证用户输入,这似乎是唯一的选择。
除了普通的 html 和 javascript 之外,我还想知道如何在React和Material-ui中做到这一点。如果我有类似以下内容,如何阻止键盘输入?
const [value, setValue] = useState(10);
return (
<React.Fragment>
<TextField
name="name"
type="number"
label="label"
inputProps={{
min: 0,
max: 100,
step: 2,
}}
defaultValue={value}
onChange={(event) => {
setValue(Number(event.target.value));
}}
/>
</React.Fragment>
);
Run Code Online (Sandbox Code Playgroud) 我正在通过阅读Learn a Haskell for Great Good 来学习 Haskell!。在“创建我们自己的类型和类型类”部分的末尾,YesNo定义了一个类来模拟 javascript 等语言的真实性:
class YesNo a where
yesno :: a -> Bool
instance YesNo Int where
yesno 0 = False
yesno _ = True
(etc.)
Run Code Online (Sandbox Code Playgroud)
在阅读参考文献之前,我试图自己充实这些实例作为练习,并认为我可以聪明地为所有Num类型定义它:
instance (Num a) => YesNo a where
yesno 0 = False
yesno _ = True
Run Code Online (Sandbox Code Playgroud)
我将跳过这需要什么FlexibleInstances,我想我已经在文档和这个答案之间理解了。一旦打开,编译器就会抱怨“约束‘Num a’不小于实例头‘YesNo a’”。这个问题的答案很好地解释了这意味着什么。使用newtype那里提供的解决方案,我想出了类似的东西
newtype TruthyNum a = TruthyNum a
instance (Num a, Eq a) => YesNo …Run Code Online (Sandbox Code Playgroud) haskell ×4
html ×1
javascript ×1
material-ui ×1
neovim ×1
pyright ×1
python ×1
reactjs ×1
rust ×1
typescript ×1
ubuntu ×1