作为对各种依赖类型化形式化技术进行调查的一部分,我遇到了一篇论文,主张使用单例类型(具有一个居民的类型)作为支持依赖类型编程的一种方式.
根据这个来源,在Haskell中,由于诱导类型/值同构,在使用单例类型时,运行时值和编译时类型之间存在分离.
我的问题是:在这方面,单身类型与类型类或引用/具体结构有何不同?
我还特别理解关于使用单一类型的类型 - 理论重要性/优点以及它们一般可以模拟依赖类型的程度的一些直观解释.
这种So类型的目的是什么?音译到Agda:
data So : Bool ? Set where
oh : So true
Run Code Online (Sandbox Code Playgroud)
So将布尔命题提升为逻辑命题.Oury和Swierstra的介绍性论文"Pi的力量"给出了一个由表格列索引的关系代数的例子.取两个表的产品要求它们具有不同的列,他们使用这些列So:
Schema = List (String × U) -- U is the universe of SQL types
-- false iff the schemas share any column names
disjoint : Schema -> Schema -> Bool
disjoint = ...
data RA : Schema ? Set where
-- ...
Product : ? {s s'} ? {So (disjoint s s')} ? RA s ? RA s' ? RA …Run Code Online (Sandbox Code Playgroud) 有创建用C定制numpy的dtypes例子在这里:
另外,似乎可以在cython中创建自定义ufunc:
似乎也应该可以使用cython创建一个dtype(然后为它创建自定义ufunc).可能吗?如果是这样,你能发一个例子吗?
使用案例:
我想做一些生存分析.基本数据元素是具有相关审查值的生存时间(浮点数)(如果关联时间表示失败时间则为假,如果它代表审查时间则为True(即,在观察期间未发生故障)).
显然,我可以使用两个numpy数组来存储这些值:时间的float数组和censor值的bool数组.但是,我想说明事件发生多次的可能性(这是一个很好的模型,比如心脏病发作 - 你可以拥有多个).在这种情况下,我需要一个对象数组,我称之为MultiEvents.每个都MultiEvent包含一系列浮点数(未经审查的失败时间)和一个观察期(也是一个浮点数).请注意,所有MultiEvents 的故障数量并不相同.
我需要能够在一个MultiEvents 数组上执行一些操作:
获取每个故障的数量
获得删失时间(即观察时间减去所有失败时间的总和)
根据其他参数数组(例如危险值数组)计算对数似然.例如,单个MultiEvent M和持续危险值的对数似然h可能是这样的:
sum(log(h) + h*t for t in M.times) - h*(M.period - sum(M.times))
M.times失败时间的列表(数组,等等)在哪里,M.period是总观察期.我希望适用适当的numpy广播规则,以便我能做到:
log_lik = logp(M_vec,h_vec)
Run Code Online (Sandbox Code Playgroud)
只要尺寸M_vec和h_vec兼容性,它就能工作.
我当前的实现使用numpy.vectorize.这工作得很好1和2,但实在是太慢了3.另请注意,我不能做这个,因为失败的我多数据对象数量不提前知道.
我想我为提出了一个有趣的“ zippy” Applicative实例Free。
data FreeMonad f a = Free (f (FreeMonad f a))
| Return a
instance Functor f => Functor (FreeMonad f) where
fmap f (Return x) = Return (f x)
fmap f (Free xs) = Free (fmap (fmap f) xs)
instance Applicative f => Applicative (FreeMonad f) where
pure = Return
Return f <*> xs = fmap f xs
fs <*> Return x = fmap ($x) fs
Free fs <*> Free xs = Free $ …Run Code Online (Sandbox Code Playgroud) 可能重复:
只需要索引:枚举或(x)范围?
哪些被认为更好/更清晰/更快/更''Pythonic'?我不关心列表的内容L,只是它有多长.
a = [f(n) for n, _ in enumerate(L)]
Run Code Online (Sandbox Code Playgroud)
要么
a = [f(n) for n in range(len(L))]
Run Code Online (Sandbox Code Playgroud)
如果它有任何区别,该功能也f可以使用len(list).
我认为ContT的正确类型应该是
newtype ContT m a = ContT {runContT :: forall r. (a -> m r) -> m r}
Run Code Online (Sandbox Code Playgroud)
和其他控制操作员
shift :: Monad m => (forall r. (a -> ContT m r) -> ContT m r) -> ContT m a
reset :: Monad m => ContT m a -> ContT m a
callCC :: ((a -> (forall r. ContT m r)) -> ContT m a) -> ContT m a
Run Code Online (Sandbox Code Playgroud)
不幸的是,我无法进行callCC类型检查,也不知道该怎么做.我设法制作shift并reset打字检查
reset :: Monad m => …Run Code Online (Sandbox Code Playgroud) 如果要从数据结构中提取元素,则必须提供其索引.但索引的含义取决于数据结构本身.
class Indexed f where
type Ix f
(!) :: f a -> Ix f -> Maybe a -- indices can be out of bounds
Run Code Online (Sandbox Code Playgroud)
例如...
列表中的元素具有数字位置.
data Nat = Z | S Nat
instance Indexed [] where
type Ix [] = Nat
[] ! _ = Nothing
(x:_) ! Z = Just x
(_:xs) ! (S n) = xs ! n
Run Code Online (Sandbox Code Playgroud)
二叉树中的元素由一系列方向标识.
data Tree a = Leaf | Node (Tree a) a (Tree a)
data TreeIx = …Run Code Online (Sandbox Code Playgroud) 在我的一个课程中,我有许多属性在获取和设置方面做了非常相似的事情.所以我将参数抽象property为工厂函数:
def property_args(name):
def getter(self):
# do something
return getattr(self, '_' + name)
def setter(self, value)
# do something
setattr(self, '_' + name, value)
return getter, setter
class MyClass(object):
def __init__(self):
self._x = None
x = property(*property_args('x')) # obviously there's more than one of these IRL
Run Code Online (Sandbox Code Playgroud)
但是,我已经发现它property实际上是一个类,并且对它进行子类化将是完美的.我在文档中找不到任何解释我需要覆盖的内容(以及参数签名__init__等),我真的不想在C源代码中寻找它.有谁知道我在哪里可以找到这些信息?
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
import Control.Comonad
import Data.Functor.Reverse
import Data.List (unfoldr)
Run Code Online (Sandbox Code Playgroud)
首先是一些背景(哈哈).我在非空列表上有拉链.
data LZipper a = LZipper (Reverse [] a) a [a]
deriving (Eq, Ord, Show, Read, Functor, Foldable, Traversable)
mkZipper :: a -> [a] -> LZipper a
mkZipper = LZipper (Reverse [])
Run Code Online (Sandbox Code Playgroud)
你可以沿着拉链向两个方向走,但你可能会掉头.
fwd, bwd :: LZipper a -> Maybe (LZipper a)
fwd (LZipper _ _ []) = Nothing
fwd (LZipper (Reverse xs) e (y:ys)) = Just $ LZipper …Run Code Online (Sandbox Code Playgroud) 我想知道做这样的事情是否不好?
data Alignment = LeftAl | CenterAl | RightAl
type Delimiter = Char
type Width = Int
setW :: Width -> Alignment -> Delimiter -> String -> String
Run Code Online (Sandbox Code Playgroud)
而不是像这样:
setW :: Int -> Char -> Char -> String -> String
Run Code Online (Sandbox Code Playgroud)
我确实知道,有效地重构这些类型什么也没做,只是占用几行以换取更清晰的代码。但是,如果我将类型Delimiter用于多种功能,那么对于导入此模块或稍后阅读代码的人来说,这将更加清晰。
我是Haskell的新手,所以我不知道这种类型的好方法是什么。如果这不是一个好主意,或者有一些可以提高清晰度的方法是可取的,那将是什么?
haskell ×6
python ×3
agda ×1
applicative ×1
callcc ×1
comonad ×1
cython ×1
free-monad ×1
functor ×1
idris ×1
iteration ×1
monads ×1
newtype ×1
numpy ×1
properties ×1
python-2.7 ×1
tree ×1
type-alias ×1
type-safety ×1
type-theory ×1
zipper ×1