Functional programming 奇怪的Haskell/GHCi问题

Functional programming 奇怪的Haskell/GHCi问题,functional-programming,ghci,haskell,Functional Programming,Ghci,Haskell,所以我有一个代码*,当取三个点时,应该返回一个方向。我已经编写了这个解决方案,但每次尝试运行它时,它都会导致GHCi冻结,所以我想知道我做错了什么。代码如下: --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))

所以我有一个代码*,当取三个点时,应该返回一个方向。我已经编写了这个解决方案,但每次尝试运行它时,它都会导致GHCi冻结,所以我想知道我做错了什么。代码如下:

--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)
——第三章问题9
数据点x y=点x y导出(等式,显示)
数据向量xy=向量xy导出(等式,显示)
子(点xy)(点ab)=(向量(x-a)(y-b))
点(矢量xy)(矢量ab)=(x*a)+(y*b)
perp(向量xy)=(向量(-y)x)
mag(向量xy)=sqrt(点v v),其中v=(向量xy)
数据方向=左转|右转|直行|倒车|停车|未定义
推导(等式,显示)
方向(点a b)(点c d)(点e f)
|a/=c&&b/=d&&c==e&&d==f=停止
|a==c&&b==d | | c==e&&d==f | | e==a&&f==b=未定义
|d>0=左转
|d<0=右转
|否则=直线
其中d=点(子p1 p0)(perp(子p2 p1))
式中p0=(a点和b点)
p1=(c点和d点)
p2=(点e和点f)
我看不到递归,所以我不明白它为什么会这样。到目前为止,Haskell编译器一直非常直言不讳地告诉我什么时候我在做一些愚蠢的事情,但这编译得很好


*这是《真实世界哈斯克尔》第三章中的第9个问题,如果你想知道的话。

你把名字绑定了两次。首先在模式
c点d
中,而不是
where
子句中


因此,如果您试图访问模式绑定的
d
,您实际上是从
where
子句中递归引用
d

谢谢,我永远也不会明白。如果您使用-Wall运行GHCi,您将得到有关此的警告。或者更好的是,添加一行“:set-Wall”到你的~/.ghci文件。你确定你的数据声明是什么意思吗?现在,你可以有一个点[字符串](点,向量),只是为了命名一个愚蠢的点类型。根据您的使用情况,声明data Point=Point Int派生(Eq,Show)不是更好吗?