2015-01-05 2 views
3

빠른 종류의 같은 <= and > 운영자 :함수 인수

-- First variant: 
qsort :: (Ord a) => [a] -> [a] 
qsort [] = [] 
qsort (x:xs) = left x ++ [x] ++ right x 
    where left n = qsort [m | m <- xs, m <= n] 
     right n = qsort [m | m <- xs, m > n] 

-- λ: qsort [10,2,5,3,1,6,7,4,2,3,4,8,9] 
-- [1,2,2,3,3,4,4,5,6,7,8,9,10] 

내가 leftright 기능 거의 동일 참조하십시오. 그러므로 나는 ... 그것을 짧은를 다시 작성하는 뭐 그런 원하는 :

-- Second variant: 
qsort' :: (Ord a) => [a] -> [a] 
qsort' [] = [] 
qsort' (x:xs) = (srt <=) ++ [x] ++ (srt >) 
    where srt f = qsort' [m | m <- xs, m f x] 

을하지만 ghci에이를로드하려고하면이 오류를 얻을 :

λ: :load temp 
[1 of 1] Compiling Main    (temp.hs, interpreted) 

temp.hs:34:18: 
    Couldn't match expected type `[a]' 
       with actual type `(t0 -> [a]) -> Bool' 
    Relevant bindings include 
     srt :: forall t. t -> [a] (bound at temp.hs:35:9) 
     xs :: [a] (bound at temp.hs:34:11) 
     x :: a (bound at temp.hs:34:9) 
     qsort' :: [a] -> [a] (bound at temp.hs:33:1) 
    In the first argument of `(++)', namely `(srt <=)' 
    In the expression: (srt <=) ++ [x] ++ (srt >) 
    In an equation for qsort': 
     qsort' (x : xs) 
      = (srt <=) ++ [x] ++ (srt >) 
      where 
       srt f = qsort' [m | m <- xs, m f x] 

temp.hs:34:37: 
    Couldn't match expected type `[a]' 
       with actual type `(t1 -> [a]) -> Bool' 
    Relevant bindings include 
     srt :: forall t. t -> [a] (bound at temp.hs:35:9) 
     xs :: [a] (bound at temp.hs:34:11) 
     x :: a (bound at temp.hs:34:9) 
     qsort' :: [a] -> [a] (bound at temp.hs:33:1) 
    In the second argument of `(++)', namely `(srt >)' 
    In the second argument of `(++)', namely `[x] ++ (srt >)' 
    In the expression: (srt <=) ++ [x] ++ (srt >) 

temp.hs:35:38: 
    Could not deduce (a ~ (t -> a -> Bool)) 
    from the context (Ord a) 
     bound by the type signature for qsort' :: Ord a => [a] -> [a] 
     at temp.hs:32:11-31 
     `a' is a rigid type variable bound by 
      the type signature for qsort' :: Ord a => [a] -> [a] 
      at temp.hs:32:11 
    Relevant bindings include 
     m :: a (bound at temp.hs:35:29) 
     f :: t (bound at temp.hs:35:13) 
     srt :: t -> [a] (bound at temp.hs:35:9) 
     xs :: [a] (bound at temp.hs:34:11) 
     x :: a (bound at temp.hs:34:9) 
     qsort' :: [a] -> [a] (bound at temp.hs:33:1) 
    The function `m' is applied to two arguments, 
    but its type `a' has none 
    In the expression: m f x 
    In a stmt of a list comprehension: m f x 
Failed, modules loaded: none. 
λ: 

내가 오류 메시지를 읽을 수 있지만 내가 돈 그 이유를 아직 이해하지 못했습니다 ...

+3

연산자 ('<=' and '>')와'f'를 역 인용 부호 ('\'')로 둘러싸면'qsort' 함수가 작동해야합니다. 역 인용 부호는 중위 연산자와 같은 이진 함수를 사용할 수 있도록합니다. – Jubobs

+0

네, 괜찮습니다. 고마워요. 그런데 백틱을 사용해야하는 이유는 무엇입니까? '<='와'<'연산자는 삽입 연산자 (infix operators)이므로 중절 삽입 폼이이 경우에 효과가있을 것으로 예상했습니다. –

+0

GHC는 "특수 문자"([this] (http://stackoverflow.com/questions/10548170/what-characters-are-permitted-for-haskell-operators) 참조)로 정의 된 함수 만 사용합니다. 태만. 예를 들어, GHCi에서'let (/./) = (+)'을 시도해보십시오. 오류없이 '1 /./ 5'와 같은 것을 쓸 수 있습니다. – Jubobs

답변

9

중괄호로 f을 사용하지 마십시오. 당신은 앞에 f을 넣고 괄호 (<=)의 기능을 표현하여 해결할 수 있습니다 : 당신이 기본적으로하고 싶은 것은 mx전화f 때문에

-- third variant: 
qsort' :: (Ord a) => [a] -> [a] 
qsort' [] = [] 
qsort' (x:xs) = (srt (<=)) ++ [x] ++ (srt (>)) 
    where srt f = qsort' [m | m <- xs, f m x] 

이 주로입니다. 이제 기본 lambda-calculus는 항상 왼쪽에 나열된 함수를 평가합니다.

하스켈은 운영자에게 문법적인 설탕만을 제공합니다. a+b을 쓸 때 기본적으로 쓰는 것은 (+) a b (커튼 뒤)입니다. 이것이 하스켈이 가장 좋아하는 부분이지만 컴파일러는 프로그래머가 편리하게 사용할 수있는 기능을 제공합니다. a*b+c*d을 쓰는 것이 (+) ((*) a b) ((*) c d)을 쓰는 것보다 훨씬 쉽지만, 두 번째 방법은 실제로 lambda-calculus에 그런 것들을 쓰는 법입니다.

연산자를 함수로 보려면 함수를 <=으로 바꾸려면 (<=)을 입력합니다.

는 편집 @Jubobs, 당신은 또한 중위를 사용할 수를 주장하지만, 이렇게 역 따옴표 사용해야합니다으로

:

-- fourth variant: 
qsort' :: (Ord a) => [a] -> [a] 
qsort' [] = [] 
qsort' (x:xs) = (srt (<=)) ++ [x] ++ (srt (>)) 
    where srt f = qsort' [m | m <- xs, m `f` x] 

문제는 주로 당신은 패스 당신의 기능에 필요 f을 통해, <=>은 기능이 아니며 (<=)(>)입니다. 기술적으로 말하자면, 이야기는 좀 더 복잡 합니다만, 기본을 배울 때 충분합니다. 사용 역 따옴표에 의해

는, 하스켈 읽기 :

x `f` y 

과 같이 사업자가 우선 순위를 또한이 있기 때문에

f x y 

(이것은 완전히 사실이 아니다 있습니다 : *+보다 더 엄격한 결합, 그러나 이것들은 프로세스의 "세부 사항"입니다.)

x o y 

o 운영자와

(o) x y 

이다 운영자 위에 괄호 넣기

반대 효과의 종류이다.

+0

고맙습니다. 하지만 왜 * 삽입 식을 사용할 수 없습니까? 두 연산자는 중위어이며 중절 삽입 호출이 작동 할 것으로 예상했습니다. –

+0

@ 부시 : 업데이트 된 대답을 참조하십시오. –