English 中文(简体)
类型串式异种列表和类型家族的默认(? )?
原标题:Type-threaded heterogenous lists and defaulting(?) with type families?

我在图书馆工作 我想给一个循环类下定义 我简化了这个分类如下:

{-# LANGUAGE MultiParamTypeClasses 
           , FlexibleInstances #-}

data Snoc st b c = Snoc (st b) (c -> b) 
data Top a = Top

class StackTo a st c  where
     runStack :: st c -> (c -> a)
instance StackTo a Top a where
     runStack _ = id
instance (StackTo a st b) => StackTo a (Snoc st b) c where
     runStack (Snoc st  cb) = runStack st  . cb

这让我做,比如说。

*Main Data.Label> let f = runStack $ Snoc (Snoc Top fst) head :: [(a,x)] -> a
*Main Data.Label> f [( a ,undefined)] 
 a 

但是,这似乎需要谨慎地使用类型说明,否则...

*Main Data.Label> let f = runStack $ Snoc (Snoc Top fst) head

<interactive>:1:1:
    No instance for (StackTo a0 Top b0)
      arising from a use of `runStack 
    Possible fix: add an instance declaration for (StackTo a0 Top b0)
    In the expression: runStack
    In the expression: runStack $ Snoc (Snoc Top fst) head
    In an equation for `it : it = runStack $ Snoc (Snoc Top fst) head

我认为这些都是在 < a href=> https://stackoverflow.com/ questions/8031288/variadic-list-list- constructor-how-to-default-to-the- 更正- type- and-get- type- safety- safett> 中处理的同样问题,但我在这里无法调整这个解决方案。我可以使用打字家庭或其他方法来为我的循环续存堆找到更方便用户的解决方案吗?

最佳回答

相关问题的答案隐藏了以下非常有用的伎俩:概括实例头,并专门处理实例背景。

instance a ~ b => StackTo a Top b where
    runStack _ = id

当选择要使用的示例时, GHC 仅检查可用的实例头 -- -- 而不是背景 -- -- 并选择匹配当前已知类型的内容的( 如果有的话) 。 它不会在做出此选择之前专门指定一种类型, 即使专门选择会允许一个或多个可用的实例头匹配。 因此, 这里给出的示例和上面问题中的示例之间的差别是比较一般的: 当中间类型为 < code> Top 时, 这个选项适用, 而只有当中间类型为 < code> Top < em > 和 < / em > 时, 你才适用。 我们足够了解其他两种类型是否相等。

你的情况会和更少的其他可能发生的情况重叠, 但这会鼓励更强烈的推论引擎。

问题回答

是否有什么特别的原因, 为什么Kleene 恒星 GADT 不做这项工作?

data Star r a b where
  Nil   :: Star r a a
  Cons  :: r a b -> Star r b c -> Star r a c

compose :: Star (->) a b -> a -> b
compose Nil          = id
compose (Cons f fs)  = compose fs . f

但如果你需要类类的方法 我会不插手的





相关问题
Euler Problem in Haskell -- Can Someone Spot My Error

I m trying my hand at Euler Problem 4 in Haskell. It asks for that largest palindrome formed by multiplying two three-digit numbers. The problem was simple enough, and I thought my Haskell-fu was up ...

How does foldr work?

Can anybody explain how does foldr work? Take these examples: Prelude> foldr (-) 54 [10, 11] 53 Prelude> foldr (x y -> (x+y)/2) 54 [12, 4, 10, 6] 12.0 I am confused about these executions....

Efficient queue in Haskell

How can I efficiently implement a list data structure where I can have 2 views to the head and end of the list, that always point to a head a tail of a list without expensive calls to reverse. i.e: ...

Problem detecting cyclic numbers in Haskell

I am doing problem 61 at project Euler and came up with the following code (to test the case they give): p3 n = n*(n+1) `div` 2 p4 n = n*n p5 n = n*(3*n -1) `div` 2 p6 n = n*(2*n -1) p7 n = n*(5*n -3)...

Ways to get the middle of a list in Haskell?

I ve just started learning about Functional Programming, using Haskel. I m slowly getting through Erik Meijer s lectures on Channel 9 (I ve watched the first 4 so far) and in the 4th video Erik ...

haskell grouping problem

group :: Ord a => [(a, [b])] -> [(a, [b])] I want to look up all pairs that have the same fst, and merge them, by appending all the list of bs together where they have the same a and discarding ...

Closest equivalent to subprocess.communicate in Haskell

I want to do a popen() / python s subprocess.communicate from Haskell - start a program, give it stdin, and get its stdout/stderr. What s the most direct / Haskellish way to do this?

热门标签