2011-07-30 2 views
4

다음 예를 고려한다 : 첫하스켈 - typeclass를 추가 하시겠습니까?

data Dot = Dot Double Double 
data Vector = Vector Double Double 

을 난 Vector 추가 할 + 연산자 과부하 싶다. 내가 평등 (==) 연산자를 오버로드 원한다면, 나는 그것을 좋아 작성합니다

instance Eq Vector where ...blahblahblah 

그러나 또한 작업과 유형처럼 Vector없이 행동을 할 Add typeclass이 있다면 내가 찾을 수 없습니다. 나도 하스켈 typeclasses의 전체 목록을 찾을 수 없다. 나는 다른 튜토리얼에서 몇 안되는 것을 알고있다. 그러한 목록이 존재합니까?

연산자를 Vector에서 Dot까지 추가로드 할 수 있습니까 (오히려 논리적 인 것 같습니까?).

+1

왜 점과 벡터를 구별해야합니까? 다른 사람들이 언급했듯이 (+)는 Num typeclass에 있지만 점과 벡터로 (+)를 구현할 수 없습니다. 두 인수는 모두 같은 유형이어야하기 때문입니다.두 유형을 상호 교환 가능하다고 생각할 수 있다면, 한 유형 만 사용할 수 있으며, 그 유형을 Num의 인스턴스로 만들 수 있습니다. – Boris

+1

아마도 'Num'을 찾고있을지라도, 'Monoid' typeclass가 당신에게 흥미있을 것입니다. 다른 리소스 중에서 [LYAH # monoids] (http://learnyouahaskell.com/functors-applicative-functors-and-monoids#monoids) –

답변

7

Prelude의 연산자 +는 typeclass Num로 정의됩니다. 그러나 이름에서 알 수 있듯이이 연산자는 추가뿐만 아니라 다른 숫자 연산 (특히 다른 산술 연산자와 숫자 리터럴을 사용할 수있는 기능)을 정의하므로 사용 사례에 맞지 않습니다.

Prelude의 + 연산자를 숨기고 싶지 않으면 (+ Integer, Double 등 자신 만의 Addable 인스턴스를 만들어야한다는 것을 제외하고는 + 유형에 대해 과부하 할 방법이 없습니다. 숫자에 +를 사용).

+3

을 참조하십시오. Num을 구현하고 연산자 (+)는 정의되지 않았습니다. 실제로, Haskell 프로그래머는 때때로 typeclasses를 구현하고 정의되지 않은 메소드를 사용하지 않을 것입니다. –

5

instance Num Vector을 벡터 추가 (및 다른 의미있는 연산자)에 대해 +에 오버로드하도록 작성할 수 있습니다.

instance Num Vector where 
    (Vector x1 y1) + (Vector x2 y2) = Vector (x1 + x2) (y1 + y2) 
    -- and so on 

그러나 모든 +이 유형 Num a => a -> a -> a, 즉 두 피연산자와 결과가 유의 동일한 유형이어야한다. 즉, DotVector을 더할 수 없으며 Dot이 될 수 없습니다.

Prelude에서 Num을 숨기고 자신의 +을 지정하더라도 혼동을 일으키고 일반 산술과 함께 사용하는 것이 더 어려워 질 수 있습니다.

난 당신이 예를

(Dot x y) `offsetBy` (Vector dx dy) = Dot (x + dx) (y + dy) 

또는 짧은 것을 선호하는 경우 기호를 사용하여 약간의 변형, 벡터 점 추가에 대한 자신의 연산자를 정의하는 것이 좋습니다.

+0

'(+)', 또는'Num' 모두를 숨기고, 대신 자신의 것을 사용하는 * 잘못된 * 것은 없습니다. 문제는 정말 못생긴 해킹이 아닌 다른 일을하기 위해서 기본적으로 대부분의 Prelude 숫자 클래스를 완전히 대체해야한다는 것입니다. –

13

하는 typeclass에 대한 정보 (있는 경우) 함수가 속한 사용하는 GHCi입니다 발견하는 쉬운 방법 :

Prelude> :i (+) 
class (Eq a, Show a) => Num a where 
    (+) :: a -> a -> a 
    ... 
     -- Defined in GHC.Num 
infixl 6 + 
4
가끔 사람들이 이러한 종류의 서곡에서 사람과 같이 그 자신의 연산자를 정의하는 참조

. ++도 두 개의 목록을 "추가"한다는 아이디어를 전달한 것이기 때문에 아마도 해당 기호를 사용하지만 목록이 Num의 인스턴스가되지는 않습니다. 따라서 <+> 또는 |+| 또는 뭔가를 사용할 수 있습니다.