我试图用java8的Collectors.toMap上Stream的ZipEntry.它可能不是最好的主意,因为在处理过程中可能会出现异常,但我想它应该是可能的.
我现在得到一个编译错误(类型推理引擎,我猜),我不明白.
这是一些提取的演示代码:
import java.io.IOException;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class TestMapCollector {
private static class MyObject {
}
public static void main(String[] argv) throws IOException {
try (ZipFile zipFile = new ZipFile("test")) {
Map<String, MyObject> result = zipFile.stream()
.map(ZipEntry::getName)
.collect(Collectors.toMap(f -> "test", f -> new MyObject()));
}
}
}
Run Code Online (Sandbox Code Playgroud)
此代码按原样构建,但如果您只是对该.map(ZipEntry::getName)行进行注释,则不会构建该代码.好像toMap收集器可以工作,如果输入是一个流String但不是输入是一个流ZipEntry?
作为参考,这是构建错误的开始,它非常模糊:
no suitable method found for collect(Collector<Object,CAP#1,Map<String,MyObject>>)
method Stream.<R#1>collect(Supplier<R#1>,BiConsumer<R#1,? super CAP#2>,BiConsumer<R#1,R#1>) …Run Code Online (Sandbox Code Playgroud) 这个问题非常简单,与类型守卫有关:
abstract class A {
abstract isB(): this is B;
abstract isC(): this is C;
abstract get(): number;
}
class B extends A {
isB(): this is B {
return true;
}
isC(): this is C {
return false;
}
get() {
return 5;
}
}
class C extends A {
isB(): this is B {
return false;
}
isC(): this is C {
return true;
}
get() {
return 6;
}
}
const x = new C();
if (x.isB()) …Run Code Online (Sandbox Code Playgroud) 我正在尝试在类方法上应用打字稿的方法重载,以用于过滤器类方法。
class Vector<T> {
static of<T>(vals: T[]): Vector<T> {
return undefined;
}
// filter<U extends T>(fn:(x:T)=>x is U): Vector<U>;
filter(fn:(x:T)=>boolean): this {
return undefined;
}
}
const v1 = Vector.of([1,2,3]).filter(x=>x>1);
Run Code Online (Sandbox Code Playgroud)
这工作正常,直到注释行被取消注释。
当取消注释该行时,我们收到错误:
ttt.ts(12,38): error TS2345: Argument of type '(x: number) => boolean' is not assignable to parameter of type '(x: number) => x is number'.
Signature '(x: number): boolean' must be a type predicate.
Run Code Online (Sandbox Code Playgroud)
所以看来 typescript (2.7.2) 忽略了重载并仅选择 的类型定义之一filter,我不明白。这种重载模式filter是相对已知的,并且由 typescript 自己的 es5.d.ts 使用,此外类也支持 …
我发现自己越来越多地经常这样做......
我有一个函数f :: IO [a]然后我想在它上面应用一个类型的函数g :: a -> b来获取IO [b].
漫长的道路是:
x <- f
let y = fmap g x
Run Code Online (Sandbox Code Playgroud)
然后我缩短为:
x <- f
let y = g <$> x
Run Code Online (Sandbox Code Playgroud)
而现在我宁愿这样做:
y <- fmap g <$> f
Run Code Online (Sandbox Code Playgroud)
但是根据Functor法律,我可以看到我甚至可以做到:
(<$$>) = fmap . fmap
y <- g <$$> f
Run Code Online (Sandbox Code Playgroud)
虽然我经常提到这一点,但我发现fmap . fmap它在基础库中没有特殊的绑定,而对我来说它似乎是一个非常频繁的习语.我真的可以在这个地方使用它!所以现在我想知道,我是不是在努力编写纯粹的代码,这就是为什么我比这更有经验的haskell程序员更多地点击它...或者是否有一种更优雅的方式来实现这一点,这解释了为什么其他人不使用这个成语许多?
例如Maybe,当我有一个值时,我想在它上面应用某些东西时,Just或者只是保留Nothing它Nothing,如果它是a ,我有很多方法可以在haskell中实现它.但是,当我想申请一个monadic动作时,我没有找到简洁的方法.
在这段代码中,d我可以使用fmap.但是我不能用它来获取,c因为那个需要monadic(IO在这种情况下)动作来应用于中的值Maybe.
import Control.Applicative
main = do
let x = Just "test.txt"
let d = reverse <$> x -- good
print d
c <- case x of -- verbose
Nothing -> return Nothing
Just y -> Just <$> readFile y
print c
Run Code Online (Sandbox Code Playgroud)
这是一种可行的方式,但它也太冗长了.
c' <- maybe (return Nothing) (\a -> Just <$> readFile a) x
print c'
Run Code Online (Sandbox Code Playgroud)
我确定有一个更短的路,我现在看不到它...
我正在阅读《球拍领域》一书,第 175 页,我实际上看到了以下代码:
(struct dice-world (src board gt))
(struct game (board player moves))
(define (no-more-moves-in-world? w)
(define tree (dice-world-gt w))
(define board (dice-world-board w))
(define player (game-player tree))
player)
Run Code Online (Sandbox Code Playgroud)
书中的函数不会返回播放器,但直到该行的所有内容都与书中一样。对我来说,这尖叫着需要模式匹配!
事实上,这很好用,对我来说可读性更强,更明确:
(define (no-more-moves+? w)
(match w
[(dice-world _ board (game _ player _)) player]))
Run Code Online (Sandbox Code Playgroud)
然而,在这里我们仍然w毫无理由地命名变量。我希望能够直接在函数参数上进行模式匹配,如下所示(无效语法):
(define (no-more-moves2? (dice-world _ board (game _ player _)))
player)
Run Code Online (Sandbox Code Playgroud)
从我到目前为止的谷歌搜索来看,这似乎不可能?这对我来说听起来难以置信吗?我猜这可能是通过一些宏技巧实现的,但我真的很惊讶这不是从书中编写代码的标准方法?作为初学者的书,我想也许稍后会介绍模式匹配,但我在索引中根本没有找到它?
另外,如果答案是不可能/不习惯,我想知道其他 lisps 是否也一样?
我正在尝试在Haskell中编写自己的配置文件系统,但我正在使用类型系统达到我的极限.我想我应该研究一下RankNTypes和ExistentialTypes,我已经尝试了一下,但我无法做到这一点.有可能它根本不可行吗?
我试图尽可能缩短代码,但这就是我现在所拥有的:
module Main where
import Data.Map as M
import Data.Maybe (fromMaybe)
import Control.Monad (liftM)
type Conf = M.Map String String
data Setting a = Setting { name :: String, defaultValue :: a }
textStroke :: Setting (Double,Double,Double,Double)
textStroke = Setting "textStroke" (1, 0.5, 0, 1)
marginXFromWidth :: Setting Double
marginXFromWidth = Setting "marginXFromWidth" 0.025
readSetting :: (Read a) => Conf -> Setting a -> a
readSetting conf (Setting key defaultV) = fromMaybe defaultV $ liftM read (M.lookup key conf) …Run Code Online (Sandbox Code Playgroud)