2013-08-08 5 views
4

저는 하스켈에서 완전한 초보자입니다. 나는 하스켈에서 사용하고 튜플의 목록을 가지고 : 그래서 튜플의 목록 인 경우 : 구조는이 [(a,b),(c,d),(e,f),(g,h)]튜플 목록에서 최대 요소 찾기

내가 원하는 것은 두 번째 값에 따라이 튜플의 최대의 요소를 반환하는 것 같다 [(4,8),(9,10),(15,16),(10,4)], 최대 요소를 (15,16)으로 지정합니다.

하지만 어떻게해야할지 모르겠다. 이것은 지금까지 내 시도,

maximum' :: (Ord a) => (Num a) => [(a,b)] -> a 
maximum' [] = error "maximum of empty list" 
maximum' [(x,y)] = -1 
maximum' (x:xs) 
    | snd x > snd(xs !! maxTail) = 0 
    | otherwise = maxTail 
    where maxTail = maximum' xs + 1 

내가 나를 위해 말도 안돼이 오류 메시지가 얻을 :

newjo.hs:23:25: 
Could not deduce (a ~ Int) 
from the context (Ord a, Num a) 
    bound by the type signature for 
      maximum' :: (Ord a, Num a) => [(a, b)] -> a 
    at newjo.hs:19:14-47 
    `a' is a rigid type variable bound by 
     the type signature for maximum' :: (Ord a, Num a) => [(a, b)] -> a 
     at newjo.hs:19:14 
In the second argument of `(!!)', namely `maxTail' 
In the first argument of `snd', namely `(xs !! maxTail)' 
In the second argument of `(>)', namely `snd (xs !! maxTail)'` 

나는이 작업을 수행하는 방법에 대한 몇 가지 도움이 필요합니다.

답변

4

솔루션을 사용하는 것입니다, 당신은 아마 당신이 쓰는 실제 코드를 사용해야합니다. 하지만 여기에는 사용중인 것과 동일한 패턴 일치 스타일을 사용하는 버전이 있습니다.

maximum' :: Ord a => [(t, a)] -> (t, a) 
maximum' []  = error "maximum of empty list" 
maximum' (x:xs) = maxTail x xs 
    where maxTail currentMax [] = currentMax 
     maxTail (m, n) (p:ps) 
      | n < (snd p) = maxTail p ps 
      | otherwise = maxTail (m, n) ps 

이 용액을 주위 저글링 인덱스를 회피하고, 대신, 전체 목록이 이송되었을 때 반환되는 현재의 최대 요소의 트랙을 유지한다. 목록으로 색인을 피하는 것은 일반적으로 우수 사례로 간주됩니다.

+0

감사. 나는 이것을 가장 좋아하지만, 다른 모든 해결책도 도움이되었다. –

20

관용적 인 방법은 maximumBy (comparing snd)을 사용하는 것입니다.

a ~ Int 메시지는 어떤 이유로 하스켈은 aInt해야한다는 추론하지만, 유형 서명이 Int들로 제한하지 않는다는 것을 의미한다. As Amos notes in the comments이고 GHC가 소스 위치를 알려주는 이유는 !!의 두 번째 인수 인 Int으로 사용하기 때문입니다.

+1

사실, 오류는 'xs !! maxTail'때문입니다. 여기서 maxTail :: a하지만 !! Int를 취한다.어떤 숫자에도 -1이 적용됩니다. –

+0

@Amos : 너무 빨리 읽고 추측을 잘못했을 것 같습니다. 수정 해줘서 고마워. – icktoofay

+5

아마도'comparison'을 사용하기 위해서는'Data.Ord'를 가져와야한다고 언급해야 할 것입니다. – firefrorefiddle

8

라이브러리를 사용하는 관용구적인 방법은 maximumBy을 사용하는 것입니다. 그런 다음 모든 남아

maximumBy :: (a -> a -> Ordering) -> [a] -> a 

은 그래서 요소를 주문하는 방법을 알고 유형 a -> a ->Ordering의 기능을 정의하는 것입니다. Ordering 객체를 구성하는 일반적인 방법은 매우 우아되었습니다 지금까지 발표

compare :: (Ord a) => a -> a -> Ordering 
1

하스켈의 튜플은 Ord의 인스턴스입니다. 따라서 그들은 명령을 받고 비교 될 수 있습니다. 그들은 너무 다음, (초 등으로 차 튜플의 첫 번째 요소에 의해 주) 사전 식 순서를 사용하여 정렬 원하는 분야

maximum [(1,1),(1,8),(2,1),(2,6)] == (2,6) 

당신이 최대 두 번째 요소로 튜플을 얻을합니다. 당신은 방금 최대 기능 튜플의 요소를 교환하고이 같은 결과 요소를 교체 할 수 있습니다 :

maximum' :: (Ord a, Ord b) => [(a,b)] -> (a,b) 
maximum' l = swap $ maximum $ map swap l 
      where swap (x, y) = (y, x) 

Ord의 인스턴스해야 모두 튜플 요소를 작동 할 수 있지만.

+0

'swap'을 정의 할 필요가 없습니다. 이미 Haskell에 있습니다 : https://hackage.haskell.org/package/base-4.10.1.0/docs/Data-Tuple.html – Elmex80s

관련 문제