2010-03-01 3 views
25

숫자 비교 목적으로 무한대를 사용했다면 간단하게 처리 할 수있는 데이터 구조를 구현하려고합니다. 값은 < = maxbound 일 수 있기 때문에 maxBound/minBound가 아니라는 점에 유의하십시오. 그러나 모든 값은 < 무한대입니다.하스켈에서는 무한대 :: Num a => a가 있습니까?

희망이 없습니까?

답변

15

어쩌면 유형을 원하십니까?

data Infinite a = Infinite | Only a 

Num a => Infinite a에 대한 Num 인스턴스를 필요한 숫자 규칙과 함께 작성하십시오.

+1

명백한 것은 해결책이 없기 때문에 기본적으로 채택했습니다 당신의 접근 방식 :'data Num a => Inf a = NegInf | 발레 | PosInf'. 당신의 도움을 주셔서 감사합니다. – me2

+25

Nooo, 데이터 선언에 형식 클래스 제약 조건을 두지 마십시오! :-) – Martijn

25

그럼 어떻습니까! 1/0을 입력하면 Infinity을 반환합니다. ghci에 :

Prelude> 1/0 
Infinity 
Prelude> :t 1/0 
1/0 :: (Fractional t) => t 
Prelude> let inf=1/0 
Prelude> filter (>=inf) [1..] 

다음의 과정은 결코 무한대보다 큰 수를 찾을 수없는, 영원히 실행됩니다. (그러나 실제 동작에 대한 자세한 내용은 [1..] 참조)

+4

IMO,'encodeFloat (floatRadix 0 - 1) (snd $ floatRange 0)'는'Infinity' (타입'(RealFrac a) => a')를 얻는 더 좋은 방법입니다. 즉, 부동 소수점 부정확 때문에'[1 ..]'는 한정된 상한선을 지나갈 수 없으므로, 여러분이 여기있는 것은 가난한 시위입니다. – ephemient

+8

Darn. 나는 그것이 한정된 양의 시간 동안 실행되는 것을 본 후에 프로그램이 영원히 돌아갈 것이라고 주장해서는 안된다는 것을 알고 있었다. – MatrixFrog

+3

오해. 어떤 점에서 꼬리는 단지'[x, x, x, x, x, x, ..]'일 것입니다. 왜냐하면'x'가 충분히 크면'x + 1 == x'가 떠 다니기 때문에, 유한의'y' (예를 들어'encodeFloat (floatRadix 0 - 1) (snd (floatRange 0) - 1)'). 분명히'x ephemient

6

다음과 같이 시도해보십시오. 그러나 Num 작업 (예 : + 또는 -)을 얻으려면 Infinitable a 유형에 Num 인스턴스를 정의해야합니다. 내가 Ord 클래스를 위해 그랬던 것처럼. 사용 사례가 가끔 점검 할 필요가 경계 조건을 가지고 있지만 때로는 아니, 당신이 이런 식으로 해결을 경우

data Infinitable a = Regular a | NegativeInfinity | PositiveInfinity deriving (Eq, Show) 

instance Ord a => Ord (Infinitable a) where 
    compare NegativeInfinity NegativeInfinity = EQ 
    compare PositiveInfinity PositiveInfinity = EQ 
    compare NegativeInfinity _ = LT 
    compare PositiveInfinity _ = GT 
    compare _ PositiveInfinity = LT 
    compare _ NegativeInfinity = GT 
    compare (Regular x) (Regular y) = compare x y  

main = 
    let five = Regular 5 
     pinf = PositiveInfinity::Infinitable Integer 
     ninf = NegativeInfinity::Infinitable Integer 
     results = [(pinf > five), (ninf < pinf), (five > ninf)] 
    in 
     do putStrLn (show results) 
+18

그건 그렇고 :'NegativeInfinity'의 경우'Infinitable' 데이터 타입을 먼저 정의한 다음'Regular'와'PositiveInfinity'를 마지막으로 정의하면 Ord '무료로. (이 방법으로 비교적 간단한 예제를 작성했다면,이 코멘트를 무시하십시오!) – yatima2975

+2

사실, 나는 이것을 알지 못했습니다. 고마워요. –

1

:

type Bound a = Maybe a 

withinBounds :: (Num a, Ord a) => Bound a -> Bound a -> a -> Bool 
withinBounds lo hi v = maybe True (<=v) lo && maybe True (v<=) hi 
16
infinity = read "Infinity" 
+0

코드가 부동 소수점 인 경우 이것이 가장 좋은 대답이라고 생각합니다. 사람들은 부동 소수점 무한대를 잊어 버리는 경향이 있습니다. – migle

2

에서 봐 내 RangedSets library, 이것은 매우 일반적인 방식으로 정확히 이것을 수행합니다. "경계"유형의 값이 주어진 "a"보다 항상 위 또는 아래가되도록 "경계"유형을 정의했습니다. 경계는 "AboveAll", "BelowAll", "Above x"및 "Below x"가 될 수 있습니다.

3
λ: let infinity = (read "Infinity")::Double 
λ: infinity > 1e100 
True 
λ: -infinity < -1e100 
True 
0

비표준 분석의 아이디어를 기반으로 한보다 원칙적인 접근법이 있습니다. 특성 제로의 완전히 정렬 된 반지 R이 주어지면 Laurent 반지 R [inf, 1/inf]를 자연 사전 편집 순서와 함께 고려할 수 있습니다. 예를 들어, 당신은 :

for all x>0 in R, 
.. -inf < -x < -d < -d^2 < .. < 0 < .. < d^2 < d < x < inf < inf^2 < .. 
where d = 1/inf. 

이 방법 로렌츠 링 R은 [inf를 1/INF]를 다시 +를 포함하여 당신이 가능하게하고 싶지는 다른 미묘한와 완전히 정렬 된 Z-대수, 즉 Num의 인스턴스이다/- 무한대, +/- 극소, 두 번째 순서의 infinitesimals 등.하지만 그것은 아르 키메디안과 유도가 더 이상 작동하지 않는 것을 유의하십시오. 이것은 2 차 산술의 일종입니다. 구현을 위해 this example을 살펴보십시오. 코드의 주석에서와 같이이 구조는 목록 모나드와 같은 다른 대수를 위해 작동해야합니다. 두 요소가 "무한히 가까운"두 번째 요소가 무한히 멀리 떨어져있는 목록을 생각할 수 있습니다. (장미 나무의 일반화로 이어진다)

관련 문제