有没有办法在Java中定义sum类型?Java似乎直接支持产品类型,我认为枚举可能允许它支持和类型,并且继承看起来可能它可以做到,但至少有一个我无法解决的情况.详细说明,sum类型是一种类型,它可以恰好具有一组不同类型中的一种,例如C中的标记联合.在我的例子中,我试图在Java中实现haskell的Either类型:
data Either a b = Left a | Right b
Run Code Online (Sandbox Code Playgroud)
但是在基础级别我不得不将其作为产品类型实现,而忽略其中一个字段:
public class Either<L,R>
{
private L left = null;
private R right = null;
public static <L,R> Either<L,R> right(R right)
{
return new Either<>(null, right);
}
public static <L,R> Either<L,R> left(L left)
{
return new Either<>(left, null);
}
private Either(L left, R right) throws IllegalArgumentException
{
this.left = left;
this.right = right;
if (left != null && right != null)
{
throw new IllegalArgumentException("An Either cannot be created …Run Code Online (Sandbox Code Playgroud) 我从可计算性理论中知道可以采用两个无限列表的交集,但我找不到在Haskell中表达它的方法.
一旦第二个列表无限,传统方法就会失败,因为您花费所有时间在第一个列表中检查它是否存在非匹配元素.
例:
let ones = 1 : ones -- an unending list of 1s
intersect [0,1] ones
Run Code Online (Sandbox Code Playgroud)
这永远不会产生1,因为它永远不会停止检查ones元素0.
一个成功的方法需要确保在有限的时间内访问每个列表的每个元素.
也许,这将通过迭代两个列表,并花费大致相等的时间来检查每个列表中的所有先前访问的元素彼此.
如果可能的话,我还想有办法忽略列表中的重复项,因为它偶尔是必要的,但这不是必需的.
我有一个Either<L, R>类,它表示两种类型之一的值或语义上不同的状态。在某些情况下,无论值是哪种选择,对其进行操作都是有价值的。
我想要(非静态)方法,它接受Consumer<T>,那里T是两者的超类型L和R,其中L和R是类的类型的参数。
目前,java让我这样做:(静态实现)
public static <T, L extends T, R extends T> void collapse(Either<L,R> e, Consumer<T> op)
Run Code Online (Sandbox Code Playgroud)
但是,当然,对于非静态实现,我不能对L和施加约束R,因为已经为所讨论的实例定义了约束。我需要施加这些约束T,但是java不允许我编写以下内容,因为它一次只允许一个类在超类型或子类型约束中。鉴于所有类都至少共享Object一个共同的超类型,这尤其令人沮丧,因此这些约束始终可以满足。
public void collapse(Consumer<? super L & R> op)
Run Code Online (Sandbox Code Playgroud)
还有其他方法可以定义此约束,在更高版本的Java中允许使用此约束的任何提示,还是对为什么它将成为破坏性功能的任何解释?
我正在定义我自己的复数数据类型作为学习练习,并且我遇到了abs与Num. 据我所知,每个类型类只允许一个实例定义,但如果可以的话,我会做这样的事情:
instance Num a => Num (Complex a) where
(+) (Complex ra ia) (Complex rb ib) = Complex (ra + rb) (ia + ib)
(-) (Complex ra ia) (Complex rb ib) = Complex (ra - rb) (ia - ib)
(*) (Complex ra ia) (Complex rb ib) = Complex (ra*rb - ia*ib) (ra*ib + rb*ia)
fromInteger r = Complex (fromInteger r) 0
instance Floating a => Num (Complex a) where
abs (Complex r i) = Complex …Run Code Online (Sandbox Code Playgroud) 我正在Result用Java 编写一个类型,我发现它需要一个执行可能失败的操作的方法,然后在新的Result对象中封装值或异常.
我曾希望这会奏效:
@FunctionalInterface
public interface ThrowingSupplier<R, E extends Throwable>
{
R get() throws E;
}
public class Result<E extends Throwable, V>
{
...
public static <E extends Throwable, V> Result<E, V> of(ThrowingSupplier<V, E> v)
{
try
{
return value(v.get());
}
catch(E e)
{
return error(e);
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
但Java无法捕获由类型参数定义的异常.我也尝试过使用instanceof,但也不能用于泛型.有什么方法可以实现这个方法吗?
这是添加of方法之前的结果类型.它的目的是类似于HaskellEither和rustResult,同时也有一个有意义的bind操作:
public class Result<E extends Throwable, V>
{
private Either<E, V> value; …Run Code Online (Sandbox Code Playgroud) 我正在制作一个目录的 tarball,其中tar -C "$DIR" -chf "$TARBALL"有一些文件不断向我发出警告,“文件在我们读取之前已被删除”。文件就在那里,并且我没有同时运行任何其他可能会覆盖文件的进程。这个错误是什么意思?
我已经定义了一个Fine-Grained Functor类(FgFunctor),以便将约束应用于可以映射到Ordered Triple数据类型(OrdTriple)的函数类型,这需要包含的类型是可订购的.
import Data.List (sort)
-- 'fine-grained' functor
class FgFunctor f a b where
fgmap :: (a -> b) -> f a -> f b
data OrdTriple a = OrdTriple a a a deriving Show
instance (Ord a, Ord b) => FgFunctor OrdTriple a b where
fgmap f (OrdTriple n d x) = OrdTriple n' d' x'
where [n', d', x'] = sort [f n, f d, f x]
main :: IO () …Run Code Online (Sandbox Code Playgroud) 我之前已经定义了一个函数,它接受一个Maybes 列表并将其转换Maybe为一个列表,如下所示:
floop :: [Maybe a] -> Maybe [a]
floop [] = Just []
floop (Nothing:_) = Nothing
floop (Just x:xs) = fmap (x:) $ floop xs
Run Code Online (Sandbox Code Playgroud)
现在我想重新定义它是一个较大的容器类,不只是名单的兼容,而且我发现,它需要实现的功能foldr,mappend,mempty,fmap,和pure; 所以我认为以下类型行是合适的:
floop :: (Foldable t, Functor t, Monoid t) => t (Maybe a) -> Maybe (t a)
Run Code Online (Sandbox Code Playgroud)
正如(我认为)它确保为给定容器实现这些功能,但是它会导致以下错误:
Expecting one more argument to ‘t’
The first argument of ‘Monoid’ should have kind ‘*’,
but ‘t’ has kind ‘* …Run Code Online (Sandbox Code Playgroud) 我在努力记住在调用Haskell函数时如何使用括号.我来自C风格的背景,我习惯于f(comma, separated, args)调用函数的语法.显然这与(在Haskell中)相同,((((f) comma) separated) args)但这只是令人困惑.
为什么我需要所有这些括号?
我正在尝试创建一个函数来执行以下操作:接受f表单fn(T) -> T
的闭包返回表单的闭包,根据 bool 参数fn(T, bool) -> T有条件地执行f。
我来自 Haskell 的背景,在 Haskell 中,这将是这样的:
conditionally :: (a -> a) -> a -> Bool -> a
conditionally f x True = f x
conditionally f x False = x
Run Code Online (Sandbox Code Playgroud)
将其转换为更像铁锈的东西:
conditionally :: ((t) -> t) -> ((t, Bool) -> t)
conditionally f = \(x, b) -> if b then (f x) else (x)
Run Code Online (Sandbox Code Playgroud)
我在 rust 中尝试了以下操作:
fn conditionally<T>(f: &'static (dyn Fn(T) -> T + …Run Code Online (Sandbox Code Playgroud) 每当我打开一个文件时,“ tabstop”选项的值都不同(不正确)。在我的.vimrc中,有以下一行:
set tabstop=4 softtabstop=4 shiftwidth=4 noexpandtab
Run Code Online (Sandbox Code Playgroud)
和“制表符”未在任何后续行中提及。当我打开正在处理的特定文件时,“ tabstop”选项设置为8,而所有其他相关选项都是正确的。和所有其他文件(到目前为止)正确显示其缩进。我还没有使用模式行或智能标签。如果我在文件中获取vimrc,它将纠正缩进,因此我假设它与vimrc没有直接关系。怎么了?
与此问题类似,是否有命令重做vim中所有未完成的更改?目前我所知道的只是1000<C-R>或类似,只是重做大量的更改,但它感觉很麻烦,而且相当随意.