Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如何将此实例方法定义移动到类默认值?_Haskell_Types_Type Families - Fatal编程技术网

Haskell 如何将此实例方法定义移动到类默认值?

Haskell 如何将此实例方法定义移动到类默认值?,haskell,types,type-families,Haskell,Types,Type Families,考虑这个类和一个示例实例 其目的是提供一个类型级别开关,允许将基本类型-Int(在本例中-)转换为经验证的谓词子类型,以供将来使用。诚然,这个类有些做作,但我从实际代码中提取了它,我会用更有用的方法填充它,只是我被卡住了 {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE TypeApplications #-} module Collection where import Da

考虑这个类和一个示例实例

其目的是提供一个类型级别开关,允许将基本类型-
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测试。)

我将处理同一基本类型上的几个子类型,这些子类型仅在
集合
的定义上有所不同,而证明方法是一致查找。因此,没有理由不为该方法提供默认代码。然而,我无法设计出这样的代码。我的第一份草稿无法进行类型检查,而第二份经过调整的草稿运行,但似乎没有终止

以下是初稿:

...
{-# 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@phantom
)实例化
collection
,这也需要
ScopedTypeVariables

更新:我现在明白了,这就是你第二次尝试的目的。问题在于,您的
where
子句定义了一个无限循环,因为RHS上的
集合
与LHS上绑定的
集合
相同(根据需要插入facepalm)

{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE TypeApplications #-}

module Collection where

import Data.Tagged

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)
    default inCollection :: ( Collection phantom ~ Tagged phantom [Int]
                            , Element phantom ~ Tagged phantom Int)
                            => Int -> Maybe (Element phantom)
    inCollection element
        | element `elem` unTagged (collection @phantom) = Just $ Tagged element
        | otherwise = Nothing

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]