2010-11-09 35 views
5

Vì vậy, tôi có một chút mã *, khi lấy ba điểm, được cho là sẽ trả về một hướng. Tôi đã viết giải pháp này, nhưng mỗi khi tôi cố gắng chạy nó, nó làm cho GHCi bị đóng băng, vì vậy tôi tự hỏi tôi đang làm gì sai. Đây là mã:Strange Haskell/GHCi issue

--chapter 3 question 9 
data Point x y = Point x y deriving (Eq, Show) 
data Vector x y = Vector x y deriving (Eq, Show) 

sub (Point x y) (Point a b) = (Vector (x-a) (y-b)) 
dot (Vector x y) (Vector a b) = (x*a)+(y*b) 
perp (Vector x y) = (Vector (-y) x) 
mag (Vector x y) = sqrt (dot v v) where v = (Vector x y) 

data Direction = LeftTurn | RightTurn | Straight | Reverse | Stop | Undefined 
    deriving (Eq, Show) 
getDirection (Point a b) (Point c d) (Point e f) 
    | a/=c && b/=d && c==e && d==f = Stop 
    | a==c && b==d || c==e && d==f || e==a && f==b = Undefined 
    | d > 0 = LeftTurn 
    | d < 0 = RightTurn 
    | otherwise = Straight 
    where d = dot (sub p1 p0) (perp (sub p2 p1)) 
      where p0 = (Point a b) 
       p1 = (Point c d) 
       p2 = (Point e f) 

Không có đệ quy nào tôi có thể thấy, vì vậy tôi không hiểu tại sao nó lại hoạt động theo cách này. Cho đến nay trình biên dịch Haskell đã rất hát về việc nói với tôi khi tôi đang làm một cái gì đó câm, nhưng điều này biên dịch tốt.

* Đây là Câu hỏi 9 của Chương 3 của "Haskell trong thế giới thực" trong trường hợp bạn đang tự hỏi.

+1

Bạn có chắc chắn rằng các khai báo dữ liệu của bạn có ý nghĩa gì, ý của bạn là gì? Tại thời điểm này, bạn có thể có một điểm [String] (điểm, Vector), chỉ để đặt tên một loại điểm ngớ ngẩn. Dựa trên cách sử dụng của bạn, nó sẽ không được tốt hơn để khai báo dữ liệu Point = Point Int Int deriving (Eq, Show)? – Boris

Trả lời

7

Bạn đang ràng buộc tên hai lần. Đầu tiên trong mẫu Point c d so với mệnh đề where.

Vì vậy, nếu bạn đang cố gắng truy cập vào d bị ràng buộc bởi mẫu, bạn đang thực sự đề cập đến các d từ khoản where đệ quy.

+0

Cảm ơn, tôi sẽ không bao giờ nghĩ ra điều đó. – horatius83

+5

Nếu bạn chạy GHCi với -Wall bạn sẽ nhận được một cảnh báo về điều này. –

+2

Hoặc thậm chí tốt hơn, thêm dòng ": set -Wall" vào tệp ~/.ghci của bạn. –