【发布时间】:2019-01-01 07:51:31
【问题描述】:
考虑这个类和一个示例实例。
目的是提供一个类型级别开关,允许将基本类型(在本例中为Int)转换为经过验证的谓词子类型,以供将来使用。当然,这个类有点做作,但我是从实际代码中提取出来的,我会用更有用的方法填充它,除非我卡住了。
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE TypeApplications #-}
module Collection where
import Data.Tagged
-- $setup
--
-- λ :set -XTypeApplications
class Collected phantom
where
type Element phantom = r | r -> phantom
type Element phantom = Tagged phantom Int
type Collection phantom = r | r -> phantom
type Collection phantom = Tagged phantom [Int]
collection :: Collection phantom
inCollection :: Int -> Maybe (Element phantom)
data Primes
instance Collected Primes
where
type Element Primes = Tagged Primes Int
type Collection Primes = Tagged Primes [Int]
collection = Tagged [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
-- inCollection :: Int -> Maybe (Element Primes)
inCollection element
| element `elem` unTagged (collection @Primes) = Just $ Tagged element
| otherwise = Nothing
-- ^
-- λ inCollection @Primes 7
-- Just (Tagged 7)
-- λ inCollection @Primes 8
-- Nothing
(这是一个可运行的代码,其中包含通过的 repl 测试。)
我将处理同一基本类型上的几个子类型,它们仅在collection 的定义上有所不同,而证明方法是一致查找。因此,没有理由没有该方法的默认代码。但是,我无法设计出这样的代码。我的第一个草稿无法进行类型检查,而第二个经过调整的草稿运行,但似乎没有终止。
这是初稿:
...
{-# LANGUAGE DefaultSignatures #-}
...
class Collected phantom
...
inCollection :: Int -> Maybe (Element phantom)
default inCollection :: ( Element phantom ~ Tagged phantom Int
, Collection phantom ~ Tagged phantom [Int] )
=> Int -> Maybe (Element phantom)
inCollection element
| element `elem` unTagged collection = Just $ Tagged element
| otherwise = Nothing
...
这是第二个:
...
{-# LANGUAGE ScopedTypeVariables #-}
...
class Collected phantom
...
inCollection :: ...
default inCollection :: ...
inCollection ...
where
collection = (collection :: Collection phantom)
(仅显示添加的部分。实例中的相应方法定义已被删除。在第二稿中,除了 pragma 之外唯一添加的是尝试键入 collection 的最后一行。)
有什么问题?可以做什么?
【问题讨论】:
标签: haskell types type-families