2017-12-09 3 views
1

첫 번째 목록이 두 번째 목록의 접두사인지 확인하는 프로그램을 작성하려고합니다. 예를 들어, [5,6]은 접두사 [1,5,6,7]입니다. 여기에 내 작업 코드가 있지만 기본적으로 나는 그것을 수행하는 방법에 대한 아이디어가 없습니다.하스켈 : 첫 번째 목록이 두 번째 목록의 접두어인지 확인하십시오.

prefix [Int] -> [Int] -> Bool 
prefix [] [] = [] 
prefix y (x:xs) 
| x == y = prefix y xs 
| otherwise = 0 

어떤 도움을 주시겠습니까?

+3

'[5,6]'는'[1,5,6,7]'의 접두어가 아니며 [1,5,6]입니다. '[5,6]'는'[1,5,6,7]'의 * sublist *입니다. –

+2

http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:isPrefixOf – melpomene

답변

4

귀하의 코드는 우리가 종류를 보면 훨씬 이해가되지 않습니다 : xInt입니다

prefix [Int] -> [Int] -> Bool 
prefix [] [] = [] 
prefix y (x:xs) 
| x == y = prefix y xs 
| otherwise = 0 

두 인수 목록 ([Int])이 있기 때문에,이 때문에 y[Int] 것을 의미하고, xs[Int]입니다. 그러나 x == y을 비교하면 목록과 요소를 비교할 수 없습니다. (==)(==) :: Eq a => a -> a -> Bool으로 정의됩니다. 첫 번째 절에 목록을 반환하지만 반환 형식은 Bool, 그리고 나중에는 0 (다시, 그것은 Bool이어야 함)를 반환 :

여기에 다른 문제가 있습니다.

함수를 정의 할 경우 먼저 특정 모델을 정의해야합니다. 목록이있는 경우 l1 목록의 접두어 l2? 경우 L1 그래서, 다음 L1에 관계없이 두 번째 목록의 가치, 항상 접두어, 빈 목록은 다음과 같습니다

prefix [] _ = True 

경우 (L1)이 목록 (예 : (x:xs))이다, 다음은 이 아니며의 경우 두 가지 경우에 접두어가 붙습니다. (1) 의 경우 l2은 빈 목록입니다. (2) 경우에 L2 ((y:ys))에서 y의 첫 번째 항목은 그래서, x 같지 않은 :

prefix _ [] = False 
prefix (x:xs) (y:ys) | x /= y = False 
        | otherwise = ... 

지금 문제는 경우 x == yprefix (x:xs) (y:ys)와 함께 할 것입니다.이 경우 우리는이 개 목록에 재귀, 그래서 너무 prefix (x:xs) (y:ys) == prefix xs ys의 결과 (경우에만 x == y에서) : 전체에 지금

     | otherwise = prefix xs ys 

또는 :

prefix :: [Int] -> [Int] -> Bool 
prefix [] _ = True 
prefix _ [] = False 
prefix (x:xs) (y:ys) | x /= y = False 
        | otherwise = prefix xs ys 

우리는 더에 식을 일반화 할 수 있습니다

: Eq a => [a] -> [a] -> BoolEq 인스턴스 어떤 유형 a와 함께 작동하도록 (그래서 a을 통해 정의 된 (==) 인스턴스가)

prefix :: Eq a => [a] -> [a] -> Bool 
prefix [] _ = True 
prefix _ [] = False 
prefix (x:xs) (y:ys) | x == y = prefix xs ys 
        | otherwise = False 

지금 우리는 또한 경비원을 제거 할 수 있으며, 대신 (&&) :: Bool -> Bool -> Bool을 사용합니다 :

보통 정 논리는 부 논리보다 쉽게 ​​이해할 수 있기 때문에3210
prefix :: Eq a => [a] -> [a] -> Bool 
prefix [] _ = True 
prefix _ [] = False 
prefix (x:xs) (y:ys) | x /= y = False 
        | otherwise = prefix xs ys 

우리는 또한, 조건을 교환 할 수 있습니다

prefix :: Eq a => [a] -> [a] -> Bool 
prefix [] _ = True 
prefix _ [] = False 
prefix (x:xs) (y:ys) = x == y && prefix xs ys 
+0

@CommuSoft 많은 감사를드립니다! – Nasser

관련 문제