在我正在阅读的代码库中,我发现了一个像这样的函数声明(缺少某些部分):
filepathNormalise :: BS.ByteString -> BS.ByteString
filepathNormalise xs
| isWindows, Just (a,xs) <- BS.uncons xs, sep a, Just (b,_) <- BS.uncons xs, sep b
= '/' `BS.cons` f xs
Run Code Online (Sandbox Code Playgroud)
逗号在这里做什么?
(只有作为奖励,如果有人知道这一点:Haskell编程中提到的这个语法是从第一原则开始的,如果是这样的话,在哪里?我记不起来了解它.)
人们采用什么方法(如果有的话)管理班级中的防护条款爆炸?例如:
public void SomeMethod<T>(string var1, IEnumerable<T> items, int count)
{
if (string.IsNullOrEmpty(var1))
{
throw new ArgumentNullException("var1");
}
if (items == null)
{
throw new ArgumentNullException("items");
}
if (count < 1)
{
throw new ArgumentOutOfRangeException("count");
}
... etc ....
}
Run Code Online (Sandbox Code Playgroud)
在我目前正在进行的项目中,有许多类在公共方法上具有类似的一组保护条款.
我知道.NET 4.0代码合同,但目前这不是我们团队的选择.
在我的C#代码中,我有一个非常开始的if语句:
if((something == -1) && (somethingelse == -1) && (etc == -1)) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
它正在增长.我认为现在必须有20个条款.
我应该怎么处理这个?
我只是想知道是否可以使用函数式编程语言(Haskell/F#/ Caml)的模式匹配工具多次匹配相同的值.
试想下面的例子:
plus a a = 2 * a
plus a b = a + b
Run Code Online (Sandbox Code Playgroud)
当使用两个相似的值(将存储在其中a)调用函数时,将调用第一个变体.
一个更有用的应用程序就是这个(简化AST).
simplify (Add a a) = Mult 2 a
Run Code Online (Sandbox Code Playgroud)
但是Haskell拒绝这些代码并警告我有相互矛盾的定义a - 我必须做明确的case/if-checks而不是找出函数是否具有相同的值.是否有任何技巧可以表明我想要匹配的变量会多次出现?
f# haskell functional-programming pattern-matching guard-clause
我同意马克·西曼的观点,即自动属性在某种程度上是邪恶的,因为它们打破了封装.但是,我确实喜欢它们带来的简洁语法,可读性和便利性.
我引用:
public string Name { get; set; }
Run Code Online (Sandbox Code Playgroud)
代码片段的问题并不在于它包含太多的仪式.问题是它破坏了封装.事实上
"[...] getter和setter没有实现封装或信息隐藏:它们是一种语言合法化的方式来违反它们."
James O. Coplien和GertrudBjørnvig.精益建筑.威利.2010. p.134.
大多数情况下,添加一个非null保护子句对于属性设置器来说已经足够了,我想知道是否有比下面的更好的方法.更好的是,我的意思是更简洁/更少重复.
使用代码合同:
private string _username;
public virtual string Username
{
get { return _username; }
set
{
Contract.Requires(value != null);
_username = value;
}
}
Run Code Online (Sandbox Code Playgroud)
使用vanilla .NET:
private string _username;
public virtual string Username
{
get { return _username; }
set
{
if (value == null) throw new ArgumentNullException("Username");
_username = value;
}
}
Run Code Online (Sandbox Code Playgroud) 我试图在一个函数中写3-4 where语句但我得到错误并且无法做到,我试图做类似的事情:
foo x=
| x == foo1 = 5
| x == foo2 =3
| x == foo3 =1
| otherwise =2
where foo1= samplefunct1 x
foo2= samplefunct2 x
foo3= samplefunct3 x
Run Code Online (Sandbox Code Playgroud)
我知道代码有点无用,但我只是写了这个来举例说明我的意思.
有没有人可以帮助我?提前致谢.
syntax haskell where-clause guard-clause function-definition
我有这个简单的F#功能:
let compareNum x =
let y = 10
match x with
| _ when x = y -> 0
| _ when x > y -> 1
| _ when x < y -> -1
Run Code Online (Sandbox Code Playgroud)
但是,F#编译器给出了"此表达式上的不完整模式匹配"警告.在这种情况下,所有案例都应涵盖所有模式.
我还在Chris Smith的第1版Programming F#book中的"Pattern Matching"部分看到了一个类似的例子.所以在F#的后期版本中可能会改变某些内容?
在haskell,人们可以写:
containsTen::Num a => Eq a => [a] -> Bool
containsTen (x : y : xs)
| x + y == 10 = True
| otherwise = False
Run Code Online (Sandbox Code Playgroud)
是否有可能在伊德里斯写一些相同的东西,而不用它ifThenElse(我的真实案例比上面的更复杂)?
我最近遇到了以下代码,这让我很困扰
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块之外。我在网上做了一些搜索,但仍然没有关于此用法的任何线索。
我通常会像这样执行警卫检查:
public void doStuff(Foo bar, Expression<Func<int, string>> pred) {
if (bar == null) throw new ArgumentNullException();
if (pred == null) throw new ArgumentNullException();
// etc...
}
Run Code Online (Sandbox Code Playgroud)
我已经看到这个额外的检查确保谓词实际上是一个lambda:
if (pred.NodeType != ExpressionType.Lambda) throw new ArgumentException();
Run Code Online (Sandbox Code Playgroud)
该ExpressionType枚举有很多可能性,但我不知道如何任何人的规定将适用,因为我假定编译器将只允许一个lambda.
Q1:这有什么好处?我们对所有输入进行彻底的保护检查,这是否会增加价值?
Q2:是否存在性能损失 - 即它需要比常规类型/边界/空检查更长的时间吗?
guard-clause ×10
c# ×4
haskell ×4
syntax ×3
f# ×2
validation ×2
ghc ×1
idris ×1
if-statement ×1
lambda ×1
refactoring ×1
structure ×1
where-clause ×1