我正在尝试在编译时以类型级别表示一个整数值,以便可以根据一些约束对其进行检查。
我希望DSL用户不必写类似的东西:
five = inc $ inc $ inc $ inc $ inc $ zero
因此,我一直试图创建的是一个将那个值提升到类型级别的函数。
即
fromInt :: Int -> repr n
fromInt n = __
这是我到目前为止尝试过的:
data Z
data S a
data IntNat a = IN Int
zero = (IN 0 :: IntNat Z)
inc :: IntNat a -> IntNat (S a)
inc (IN i) = (IN (i + 1))
fromInt :: Int -> IntNat a
fromInt 0 = (IN 0 :: IntNat Z)
fromInt n = inc (fromInt (n - 1))
但是,这失败了,因为我对IntNat IntNat Z ~/~ IntNat S Z
没有足够的概括。
这种方法是否普遍存在缺陷,还是需要将S Z
封装在类型族/类型类中?
这的另一个经典示例是使用类型级别长度注释的向量时生成特定长度的向量。该功能应该解决我遇到的相同问题。
答案 0 :(得分:3)
由于Haskell没有依赖类型,因此无法将值级别image.setImageObserver(button)
提升为自然类型。根据您的用例,您有几种近似选择。
arr = ["bunny", "watch", "book"]
title = ("The book of coding. (e-book) by Seb Tota").lower()
length = len(arr)
for i in range(0,length - 1):
if arr[i] in title:
print "dont click"
else:
print "click"
.addOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
navigationExpandableListView.setSelected(groupPosition, childPosition);
if (groupPosition == 0)
if (groupPosition == 1)
if (groupPosition == 2)
if (id == 0) {
Common.showToast(context, "Man's Fashion");
Intent intent = new Intent(MainActivity.this, test.class);
startActivity(intent);
} else if (id == 1) {
Common.showToast(context, "Woman's Fashion");
} else if (id == 2) {
Common.showToast(context, "Babies and Family");
} else if (id == 3) {
Common.showToast(context, "Health");
}
drawer.closeDrawer(GravityCompat.START);
return false;
}
});
navigationExpandableListView.expandGroup(2);
}
Int
答案 1 :(得分:2)
我希望DSL用户不必写类似的东西:
five = inc $ inc $ inc $ inc $ inc $ zero
您可以轻松地为它写一个准引号,但是在这种情况下,您可以使用GHC对类型级Nat文字的支持,使用类型族(它们是类型级函数)转换为表示形式。 / p>
{-# LANGUAGE DataKinds, TypeOperators, KindSignatures, TypeFamilies, UndecidableInstances #-}
import GHC.TypeLits
import Data.Proxy
data Z
data S a
type family FromNat (n :: Nat) where
FromNat 0 = Z
FromNat n = S (FromNat (n - 1))
fromNat :: Proxy n -> Proxy (FromNat n)
fromNat _ = Proxy
您还会得到诸如类型级加法之类的东西
*Main GHC.TypeLits Data.Proxy> :t fromNat (Proxy :: Proxy 5)
fromNat (Proxy :: Proxy 5) :: Proxy (S (S (S (S (S Z)))))
*Main GHC.TypeLits Data.Proxy> :t fromNat (Proxy :: Proxy (3 + 2))
fromNat (Proxy :: Proxy (3 + 2)) :: Proxy (S (S (S (S (S Z)))))
编辑:首先给出答案,但将其作为替代实现