我的问题可能最容易以一个例子的形式解释:
type family Take (n :: Nat) (xs :: [k]) :: [k]
type instance Take 0 xs = '[]
type instance Take (n+1) (x ': xs) = x ': Take n xs
Run Code Online (Sandbox Code Playgroud)
但是,这里的第二个实例被拒绝,因为(+)作为一个类型族本身,不能在参数中使用.但似乎没有任何Succ或任何通常用于匹配Nats的东西.
所以,这可以表达出来; 如果是的话,怎么样?
更新.我注意到isZero和isEven函数在GHC.TypeLits"Destructing type-nats"标题下.它们是否意味着以某种方式在类型级别使用?我怀疑不会......但主要是因为我看不出怎么样.:)
我试图定义使用ekmett的库抽象语法类型bound和free.我有一些工作,我可以删除到以下最小的例子:
{-# LANGUAGE DeriveFunctor #-}
import Bound
import Control.Monad.Free
type Id = String
data TermF f ? =
AppF ? ?
| BindF Id (Scope () f ?)
deriving Functor
newtype Term' ? = T {unT :: Free (TermF Term) ?}
type Term = Free (TermF Term')
Run Code Online (Sandbox Code Playgroud)
最后两行是,呃,不是我所希望的.它们使得PITA实际上可以利用注释(或其他)的开放递归.
是否有更好的方法将这两个库一起使用,和/或我应该放弃尝试制作Term一个免费的monad?
一个人为的例子:
signature A =
sig
type t
val x: t
end
signature B =
sig
type t
val y: t
end
signature C = sig include A B end
Run Code Online (Sandbox Code Playgroud)
显然,这将导致中的type t两次投诉C。但是有什么方法可以表达我希望两者t相等,最后是:
signature C =
sig
type t
val x: t
val y: t
end
Run Code Online (Sandbox Code Playgroud)
我尝试了各种愚蠢的语法,例如include B where type t = A.t,这并不奇怪。有什么我忘记尝试的东西吗?
另外,我知道可以通过检查语言的语法来发现(或缺少)任何明显的答案,但是我在互联网上的任何地方都找不到完整的语法。
(FWIW,我尝试这样做的实际原因是Haskell风格的monad之类的东西,其中a MonadPlus只是a Monad和an 的混合体Alternative;此刻我只是重复ALTERNATIVEin 的内容MONAD_PLUS,这对我的影响不那么大比理想的。)
在OCaml中,您可以嵌套签名:
module type FOO =
sig
module type BAR
(* … *)
end
Run Code Online (Sandbox Code Playgroud)
我只是想知道是否有人在使用中有任何这样的例子,因为我想不出任何需要它的地方.我想它在函子的返回签名中可能很有用,但我想不出任何具体的东西.
假设我在 C 中有这个结构:
/* C */
struct foo {
char *name;
int (*links)(foo*);
/* ... */
};
Run Code Online (Sandbox Code Playgroud)
如果有x :: Ptr Foo,我怎样才能得到一个FunPtrto x's links,而不使用castPtrToFunPtr?我想避免这种情况,因为 Haddocks 中关于函数和非函数具有不同地址范围(可能还有大小?)的警告,因此转换可能会导致这些平台上出现问题行为。