我正在实现内部产品的概念,这种概念在容器和数字类型上是一般的。该定义指出此操作的返回类型是(非负)实数。
一个选项(如下所示)是为每种数字类型(Float,Double,Complex Float,Complex Double,Complex CFloat,Complex CDouble等)手动编写所有实例。原始类型并不多,但我不喜欢重复。
我认为另一种选择是使用具有约束的参数化实例,例如RealFloat
(代表Float
和Double
)。
{-# language MultiParamTypeClasses, TypeFamilies, FlexibleInstances #-}
module Test where
import Data.Complex
class Hilbert c e where
type HT e :: *
dot :: c e -> c e -> HT e
instance Hilbert [] Double where
type HT Double = Double
dot x y = sum $ zipWith (*) x y
instance Hilbert [] (Complex Double) where
type HT (Complex Double) = Double
a `dot` b = realPart $ sum $ zipWith (*) (conjugate <$> a) b
为什么下面的实例不起作用(“无法将类型e
与Double
匹配..预期类型HT e
,实际类型e
”)?
instance RealFloat e => Hilbert [] e where
type HT e = Double
dot x y = sum $ zipWith (*) x y
答案 0 :(得分:3)
嗯,该特定实例不起作用,因为Double
仅产生e
,但您希望结果为RealFrac
。由于Real
约束为Fractional
,但这很容易解决,因为任何 dot x y = realToFrac . sum $ zipWith (*) x y
(虽然在数学上是可疑的)都可以转换为{{ 1}}:
instance RealFloat e => Hilbert [] e where
但是,该通用实例会阻止您定义复杂实例:使用Complex
覆盖所有类型,即使它们不是真正的实数。您仍然可以将* -> *
实例化为重叠的实例,但如果我能帮助它,我宁愿远离那些。
如果应该在public static Stream<String> readFileInChunks(String filePath, int chunkSize) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(filePath));
Iterator<String> iter = new Iterator<String>() {
String nextChunk = null;
@Override
public boolean hasNext() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < chunkSize; i++) {
try {
String nextLine = br.readLine();
if (nextLine == null) break;
sb.append(nextLine).append("\n");
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
if (sb.length() == 0) {
nextChunk = null;
return false;
} else {
nextChunk = sb.toString();
return true;
}
}
@Override
public String next() {
if (nextChunk != null || hasNext()) {
String chunk = nextChunk;
nextChunk = null;
return chunk;
} else {
throw new NoSuchElementException();
}
}
};
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
iter, Spliterator.ORDERED | Spliterator.NONNULL), false)
.onClose(() -> {
try {
br.close();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
}
上定义这样的矢量空间类,那也是值得怀疑的。是的,linear
也是这样做的,但IMO参数在这个应用程序中并不适合我们。你看过vector-space
package了吗?记住,做严肃的线性代数并不完全完整;我希望用我的linearmap-category
package来填补空白。