小编Khu*_*rya的帖子

为什么 GHC.Types.Any 在这里?

刚才我在 Haskell 中做一些代码高尔夫,我遇到了一个当时对我没有多大意义的错误。决定在 GHCi 中检查一下,现在我真的很困惑。

?> :t replicate <$> readLn
replicate <$> readLn :: IO (a -> [a])
?> f <- replicate <$> readLn
-- I type 4 and press Enter
?> :t f
f :: GHC.Types.Any -> [GHC.Types.Any]
Run Code Online (Sandbox Code Playgroud)

为什么f不是类型a -> [a]?我unsafeCoerce当然可以,但那又长又丑。

haskell types coercion ghc

11
推荐指数
1
解决办法
175
查看次数

访问泛型类型的静态字段

我是否可以要求实现接口的类具有某个静态字段或方法,并通过泛型类型参数访问/调用该字段或方法?

我有一个接口,Arithmetical<T>它指定了几个函数,如T plus(T o)T times(T o).我也有一个Vector<N extends Arithmetical<N>>类,它用于具有类型组件的向量(可变维度)N.然而,当我尝试实现点积时,我遇到了一个问题.

我想实现这个方法N dot(Vector<N> o).对于这一点,我打算开始与任何N的零是通过这两个迭代Vector<N>S' List<N>S,将每一对元素的产品给我的总.有没有一种方法可以指定Arithmetical<T>所有实现类必须有一个静态(最好是最终的)字段,ZERO并且开始dot(Vector<N> o)的主体有一些类似的东西N sum = N.ZERO;

如果没有,那么这个问题还有什么其他方法呢?我想允许0维向量,所以我不能仅仅通过将向量的第一个组件相乘来开始.有没有办法实例化泛型类型的对象,所以我只能指定一个T zero()方法Arithmetical<T>

我有理由不使用Java的数字类型 - 我希望有复杂组件的向量.

这是算术:

public interface Arithmetical<T> {
    public T plus(T o);
    public T minus(T o);
    public T negate();
    public T times(T o);
    public T over(T o);
    public T inverse();
    // …
Run Code Online (Sandbox Code Playgroud)

java generics inheritance interface

6
推荐指数
1
解决办法
426
查看次数

列表的替代方案

现在有几次,我发现自己定义了:

(<?>) :: [a] -> [a] -> [a]
[] <?> ys = ys
xs <?> _  = xs
Run Code Online (Sandbox Code Playgroud)

当然,这是一个关联操作,空列表[]既是左标识又是右标识。它的功能类似于 Python 的or.

在我看来,这会是一个很好的(<|>),比原来更好的(++)。选择第一个非空列表感觉更像是我对命名类型类的期望,Alternative而不是连接列表。诚然,它不太合适MonadPlus,但我认为为救赎付出的代价很小。我们已经在标准库中拥有(++)和;(<>)我们是否需要另一个同义词,或者一个新函数(据我所知)会更有帮助吗?

我起初认为这可能是一个很好的Alternative例子,但在相关问题的答案ZipList之后的讨论让我相信了事实并非如此。除了向后兼容性和保持明智之外,当前实例而不是这个新实例还有什么理由呢?MonadPlus

haskell list applicative alternative-functor monadplus

6
推荐指数
1
解决办法
366
查看次数

Haskell中的懒惰加泰罗尼亚语数字

我将如何有效地生成加泰罗尼亚数字的无限列表?我现在拥有的东西运行得相当快,但是在我看来,应该有一个更好的方法。

c 1 = 1
c n = sum (zipWith (*) xs (reverse xs)) : xs
    where xs = c (n-1)

catalan = map (head . c) [1..]
Run Code Online (Sandbox Code Playgroud)

我尝试使用fix代替,但是lambda不够懒惰,无法终止计算:

catalan = fix (\xs -> xs ++ [zipWith (*) xs (reverse xs)])
Run Code Online (Sandbox Code Playgroud)

我意识到(++)这不是理想的

是否存在这样的更好方法?可以使该功能足够懒惰吗?我知道 n 有一个明确的公式,但我宁愿避免使用它。

recursion haskell numbers catalan

3
推荐指数
1
解决办法
180
查看次数

为什么 ParsecT 没有 MonadWriter 实例?

今天早些时候我正在写一些 Haskell。想出了一些类似的东西

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype Foo a = Foo { ParsecT String () (Writer DefinitelyAMonoid) a }
    deriving (Functor, Applicative, Monad, MonadWriter DefinitelyAMonoid)
Run Code Online (Sandbox Code Playgroud)

这没有编译。“没有(MonadWriter DefinitelyAMonoid (ParsecT String () (Writer DefinitelyAMonoid)))从数据类型声明的‘派生’子句引起的实例”,GHC 告诉我。所以我决定看看其他一些 MTL 类是否可行,他们确实做到了。ReaderMonadReaderWriterMonadWriter。所以我转身被 Discord 用户引导到Hackage,问题很明显:

MonadState  s m => MonadState  s (ParsecT s' u m)
MonadReader r m => MonadReader r (ParsecT s  u m)
MonadError  e m => MonadError  e (ParsecT s  u …
Run Code Online (Sandbox Code Playgroud)

monads haskell parsec monad-transformers

3
推荐指数
1
解决办法
74
查看次数

为什么main的返回不是退出代码?

C和C ++允许我们从中返回退出代码main。为什么Haskell不这样做?在我看来,这很简单;只是要求main :: IO Int而不是IO t

我意识到以下内容不会像C程序员所期望的那样:

main :: IO Int
main = do
    return 1                   -- Execution continues, thanks to (>>)
    putStrLn "Unreachable?"
    return 2                   -- Exit code 2?
Run Code Online (Sandbox Code Playgroud)

这种退出代码执行起来可能很棘手,但实际上有多么棘手?对我来说,似乎比必须导入好System.Exit

haskell exit-code

2
推荐指数
1
解决办法
93
查看次数