2017-09-07 2 views
1

하스켈에서 서브 클래 싱을 사용하여 클래스에 점진적 특수성을 적용하고 운이 없다.Haskell에서 서브 클래 싱을 사용하여 점진적 특수성을 적용하는 방법?

내 첫 번째 시도 :

module Subclassing where 

class SuperClass a where 
    type TheType a :: * 
    theFunc :: TheType a -> TheType a 

class SuperClass b => SubClass b where 
    type TheType b = Int 

data MyType 

instance SubClass MyType where 
    theFunc x = x + x 

이 나왔고 :

서브 클래스에 슈퍼 클래스 '유형/방법을 노출에 대한 몇 가지 구문 방법이 있다면 내가 궁금
Subclassing.hs:10:8: error: 
    ‘TheType’ is not a (visible) associated type of class ‘SubClass’ 

Subclassing.hs:15:3: error: 
    ‘theFunc’ is not a (visible) method of class ‘SubClass’ 

. 그래서 저는 그물 주위를 조금 샅샅이 조사했지만 아무 것도 찾지 못했습니다. 그것은이 나왔고

{-# LANGUAGE TypeFamilies   #-} 
{-# LANGUAGE AllowAmbiguousTypes #-} 
{-# LANGUAGE FlexibleInstances  #-} 
{-# LANGUAGE UndecidableInstances #-} 

module Subclassing where 

class SuperClass a where 
    type TheType a :: * 
    theFunc :: TheType a -> TheType a 

class SubClass b 
instance SubClass c => SuperClass c where 
    type TheType c = Int 

data MyType 

instance SubClass MyType 
instance SuperClass MyType where 
    theFunc x = x + x 

testFunc :: SuperClass d => [TheType d] -> TheType d 
testFunc = sum . (map theFunc) 

: 내 두 번째 시도에서

, 나는 서브 클래스에 제약, 슈퍼 클래스의 보편적 인 인스턴스를 정의하여 문제를 강제로 시도에서

Subclassing2.hs:25:23: error: 
    • Overlapping instances for SuperClass a0 
     arising from a use of ‘theFunc’ 
     Matching givens (or their superclasses): 
     SuperClass d 
      bound by the type signature for: 
        testFunc :: SuperClass d => [TheType d] -> TheType d 
      at Subclassing2.hs:24:1-52 
     Matching instances: 
     instance SubClass c => SuperClass c 
      -- Defined at Subclassing2.hs:15:10 
     instance SuperClass MyType -- Defined at Subclassing2.hs:21:10 
     (The choice depends on the instantiation of ‘a0’) 
    • In the first argument of ‘map’, namely ‘theFunc’ 
     In the second argument of ‘(.)’, namely ‘(map theFunc)’ 
     In the expression: sum . (map theFunc) 

을 내 세 번째 시도, 클래스보다는 오히려 형식을 서브 클래스 만들기. 는 (나는이 때문에 newtype은 값 생성자의 단일 필드 제한으로 제한 적용을했을 것을 깨달았지만, 생각에서였다.) :

{-# LANGUAGE TypeFamilies   #-} 
{-# LANGUAGE AllowAmbiguousTypes #-} 

module Subclassing where 

class SuperClass a where 
    type TheType a :: * 
    theFunc :: TheType a -> TheType a 

newtype SubClass = SubClass { unSubClass :: Int -> Int } 
instance SuperClass SubClass where 
    type TheType SubClass = Int 
    theFunc = unSubClass 

testFunc :: SuperClass d => [TheType d] -> TheType d 
testFunc = sum . (map theFunc) 

그리고이 산출 :

Subclassing3.hs:17:13: error: 
    • Couldn't match type ‘Int -> Int’ with ‘Int’ 
     Expected type: TheType SubClass -> TheType SubClass 
     Actual type: SubClass -> Int -> Int 
    • In the expression: unSubClass 
     In an equation for ‘theFunc’: theFunc = unSubClass 
     In the instance declaration for ‘SuperClass SubClass’ 

Subclassing3.hs:20:23: error: 
    • Couldn't match type ‘TheType a0’ with ‘TheType d’ 
     Expected type: TheType a0 -> TheType d 
     Actual type: TheType a0 -> TheType a0 
     NB: ‘TheType’ is a type function, and may not be injective 
     The type variable ‘a0’ is ambiguous 
    • In the first argument of ‘map’, namely ‘theFunc’ 
     In the second argument of ‘(.)’, namely ‘(map theFunc)’ 
     In the expression: sum . (map theFunc) 
    • Relevant bindings include 
     testFunc :: [TheType d] -> TheType d 
      (bound at Subclassing3.hs:20:1) 
+2

나는 당신이 클래스가 무엇인지에 대해 매우 고심하지 않았다고 생각한다. Haskell 타입 클래스는 전형적인 OO 언어의 클래스와 매우 다릅니다. 클래스의 _ 인스턴스 _ 정의 (세 번째 시도에서 newtype처럼 구체적인 유형에 대해 수행 할 수 있음)를 정의하는 것은 근본적으로 하위 클래스를 정의하는 것과 다릅니다. – leftaroundabout

+3

[XY] (https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) 질문에 대한 답을 얻으려면, 당신이 무엇에 대해 좀 더 알고있는 것이 유용 할 것입니다. 이 모든 걸 원해. 특히, TheType 형식의 패밀리는 의미가없는 것처럼 보입니다. 왜 거기에 관련 유형의 가족이 필요하다고 생각하니? – leftaroundabout

+1

이것은 하스켈이 지원하도록 제작 된 것이 아닙니다. 즉, 나는 얼마 전이 개념에 대한 증명 (https://gist.github.com/harpocrates/38ec83098cd45d7e8bccbb2d7001acb5#file-subtype-hs)을 만들었다. 그게 당신이 찾고있는 경우, 질문은 아마도 https://stackoverflow.com/q/41504364/3072788의 중복입니다. – Alec

답변

0

첫 번째 추측은 나에게는 충분히 합리적이지만, 하스켈은 (하위) 클래스 정의에서 관련 유형 또는 메소드를 정의하지 못하게합니다.

관련 문제