Форум программистов, компьютерный форум, киберфорум
Haskell
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.98/47: Рейтинг темы: голосов - 47, средняя оценка - 4.98
5 / 5 / 1
Регистрация: 20.09.2015
Сообщений: 86
1

Variable not in scope

25.05.2018, 04:30. Показов 8717. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Пытаюсь загрузить модуль в ghci, но выдаёт ошибки

C:\Users\Egor\Documents\HaskellCoursework\Second.hs:85:5: error:
Variable not in scope:
applyViewPortToPicture
:: Graphics.Gloss.Data.ViewPort.ViewPort -> Picture -> Picture
|
85 | applyViewPortToPicture port $
| ^^^^^^^^^^^^^^^^^^^^^^

C:\Users\Egor\Documents\HaskellCoursework\Second.hs:89:61: error:
Variable not in scope: graphEdges :: Graph -> Set Edge
|
89 | edges = Pictures [drawEdge e sc | e <- Set.toList (graphEdges gr)]
| ^^^^^^^^^^

C:\Users\Egor\Documents\HaskellCoursework\Second.hs:99:40: error:
* Variable not in scope: normaliseV :: Point -> Vector
* Perhaps you meant `normalizeV' (imported from Graphics.Gloss.Data.Vector)
|
99 | if l > 0 then (charge / l) `mulSV` normaliseV d else 0
| ^^^^^^^^^^

C:\Users\Egor\Documents\HaskellCoursework\Second.hs:154:22: error:
Variable not in scope:
invertViewPort
:: Graphics.Gloss.Data.ViewPort.ViewPort -> (Float, Float) -> Point
|
154 | case findVertex (invertViewPort port pos) (viewPortScale port) sc of
| ^^^^^^^^^^^^^^

C:\Users\Egor\Documents\HaskellCoursework\Second.hs:154:48: error:
Variable not in scope:
viewPortScale :: Graphics.Gloss.Data.ViewPort.ViewPort -> Float
|
154 | case findVertex (invertViewPort port pos) (viewPortScale port) sc of
| ^^^^^^^^^^^^^

C:\Users\Egor\Documents\HaskellCoursework\Second.hs:165:33: error:
Variable not in scope:
invertViewPort
:: Graphics.Gloss.Data.ViewPort.ViewPort -> (Float, Float) -> Point
|
165 | sc{scPoints = Map.insert v (invertViewPort port pos) pts}
| ^^^^^^^^^^^^^^
Failed, no modules loaded.
Prelude>
Вот код модуля:
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Set (Set)
import qualified Data.Set as Set
import System.Random
 
import Graphics.Gloss
import Graphics.Gloss.Data.Vector
import Graphics.Gloss.Data.ViewState
import Graphics.Gloss.Interface.Pure.Game
 
type Vertex = Int
type Edge = (Vertex, Vertex)
-- INVARIANT Every `Vertex` present in a set of neighbours is
-- present as a key in the `Map`.
newtype Graph = Graph {grNeighs :: Map Vertex (Set Vertex)}
 
emptyGraph :: Graph
emptyGraph = Graph Map.empty
 
addVertex :: Vertex -> Graph -> Graph
addVertex v (Graph neighs) =
    Graph $ case Map.lookup v neighs of
                Nothing -> Map.insert v Set.empty neighs
                Just _  -> neighs
 
addEdge :: Edge -> Graph -> Graph
addEdge (v1, v2) gr = Graph neighs
  where
    gr'    = addVertex v1 (addVertex v2 gr)
    neighs = Map.insert v1 (Set.insert v2 (vertexNeighs v1 gr')) $
             Map.insert v2 (Set.insert v1 (vertexNeighs v2 gr')) $
             grNeighs gr'
 
vertexNeighs :: Vertex -> Graph -> Set Vertex
vertexNeighs v (Graph neighs) = neighs Map.! v
 
-- INVARIANT The keys in `scGraph` are the same as the keys
-- in `scPoints`.
data Scene =
    Scene { scGraph     :: Graph
          , scPoints    :: Map Vertex Point
          , scSelected  :: Maybe Vertex
          , scViewState :: ViewState }
 
emptyScene :: Scene
emptyScene =
    Scene{ scGraph     = emptyGraph
         , scPoints    = Map.empty
         , scSelected  = Nothing
         , scViewState = viewStateInit }
 
scAddVertex :: Vertex -> Point -> Scene -> Scene
scAddVertex v pt sc@Scene{scGraph = gr, scPoints = pts} =
    sc{scGraph = addVertex v gr, scPoints = Map.insert v pt pts}
 
scAddEdge :: Edge -> Scene -> Scene
scAddEdge e@(v1, v2) sc@Scene{scGraph = gr, scPoints = pts} =
    if Map.member v1 pts && Map.member v2 pts
    then sc{scGraph = addEdge e gr}
    else error "scAddEdge: non existant point!"
 
vertexPos :: Vertex -> Scene -> Point
vertexPos v Scene{scPoints = pts} = pts Map.! v
 
vertexRadius :: Float
vertexRadius = 6
 
vertexColor :: Color
vertexColor = makeColor 1 0 0 1 -- Red
 
edgeColor :: Color
edgeColor = makeColor 1 1 1 0.8 -- Whiteish
 
drawVertex :: Vertex -> Scene -> Picture
drawVertex v sc =
    Translate x y (ThickCircle (vertexRadius / 2) vertexRadius)
  where (x, y) = vertexPos v sc
 
drawEdge :: Edge -> Scene -> Picture
drawEdge (v1, v2) sc = Line [vertexPos v1 sc, vertexPos v2 sc]
 
drawScene :: Scene -> Picture
drawScene sc@Scene{scGraph = gr, scViewState = ViewState{viewStateViewPort = port}} =
    applyViewPortToPicture port $
    Pictures [Color edgeColor edges, Color vertexColor vertices]
  where
    vertices = Pictures [drawVertex n sc | n <- Map.keys (grNeighs gr)    ]
    edges    = Pictures [drawEdge e sc   | e <- Set.toList (graphEdges gr)]
 
charge :: Float
charge = 100000
 
pushForce :: Point         -- Vertex we're calculating the force for
          -> Point         -- Vertex pushing the other away
          -> Vector
pushForce v1 v2 =
    -- If we are analysing the same vertex, l = 0
    if l > 0 then (charge / l) `mulSV` normaliseV d else 0
  where
    d = v1 - v2
    l = magV d ** 2
 
stiffness :: Float
stiffness = 1 / 2
 
pullForce :: Point -> Point -> Vector
pullForce v1 v2 = stiffness `mulSV` (v2 - v1)
 
updatePosition :: Float       -- Time since the last update
               -> Vertex      -- Vertex we are analysing
               -> Scene
               -> Point       -- New position
updatePosition dt v1 sc@Scene{scPoints = pts, scGraph = gr} =
    v1pos + pull + push
  where
    v1pos  = vertexPos v1 sc
 
    -- Gets a velocity by multiplying the time by the force (we take
    -- the mass to be 1).
    getVel f v2pos = dt `mulSV` f v1pos v2pos
 
    -- Sum all the pushing and pulling.  All the other vertices push,
    -- the connected vertices pull.
    push = Map.foldr' (\v2pos -> (getVel pushForce v2pos +)) 0 pts
    pull = foldr (\v2pos -> (getVel pullForce v2pos +)) 0
                 [vertexPos v2 sc | v2 <- Set.toList (vertexNeighs v1 gr)]
 
updatePositions :: Float -> Scene -> Scene
updatePositions dt sc@Scene{scSelected = sel, scGraph = Graph neighs} =
    foldr f sc (Map.keys neighs)
  where
    f n sc' =
        let pt = if Just n == sel
                 then vertexPos n sc else updatePosition dt n sc'
        in scAddVertex n pt sc'
 
inCircle :: Point             -- Where the user has clicked
         -> Float             -- The scaling factor in the ViewPort
         -> Point             -- The position of the vertex
         -> Bool
inCircle p sca v = magV (v - p) <= vertexRadius * sca
 
findVertex :: Point -> Float -> Scene -> Maybe Vertex
findVertex p1 sca Scene{scPoints = pts} =
    Map.foldrWithKey' f Nothing pts
  where
    f _ _  (Just v) = Just v
    f v p2 Nothing  = if inCircle p1 sca p2 then Just v else Nothing
 
handleEvent :: Event -> Scene -> Scene
 
handleEvent (EventKey (MouseButton LeftButton) Down Modifiers{ctrl = Down} pos) sc =
    case findVertex (invertViewPort port pos) (viewPortScale port) sc of
        Nothing -> sc
        Just v  -> sc{scSelected = Just v}
  where
    viewState = scViewState sc
    port      = viewStateViewPort viewState
 
handleEvent (EventKey (MouseButton LeftButton) Up _ _) sc@Scene{scSelected = Just _} =
    sc{scSelected = Nothing}
 
handleEvent (EventMotion pos) sc@Scene{scPoints = pts, scSelected = Just v} =
    sc{scPoints = Map.insert v (invertViewPort port pos) pts}
 where
   port = viewStateViewPort (scViewState sc)
 
handleEvent ev sc =
    sc{scViewState = updateViewStateWithEvent ev (scViewState sc)}
 
-- Taken from <http://www.graphviz.org/Gallery/undirected/transparency.gv.txt>.
sampleGraph :: [Edge]
sampleGraph =
    [(1,  30), (1,  40), (8,  46), (8,  16), (10, 25), (10, 19), (10, 33),
     (12, 8 ), (12, 36), (12, 17), (13, 38), (13, 24), (24, 49), (24, 13),
     (24, 47), (24, 12), (25, 27), (25, 12), (27, 12), (27, 14), (29, 10),
     (29, 8 ), (30, 24), (30, 44), (38, 29), (38, 35), (2,  42), (2,  35),
     (2,  11), (14, 18), (14, 24), (14, 38), (18, 49), (18, 47), (26, 41),
     (26, 42), (31, 39), (31, 47), (31, 25), (37, 26), (37, 16), (39, 50),
     (39, 14), (39, 18), (39, 47), (41, 31), (41, 8 ), (42, 44), (42, 29),
     (44, 37), (44, 32), (3,  20), (3,  28), (6,  45), (6,  28), (9,  6 ),
     (9,  16), (15, 16), (15, 48), (16, 50), (16, 32), (16, 39), (20, 33),
     (33, 9 ), (33, 46), (33, 48), (45, 15), (4,  17), (4,  15), (4,  12),
     (17, 21), (19, 35), (19, 15), (19, 43), (21, 19), (21, 50), (23, 36),
     (34, 23), (34, 24), (35, 34), (35, 16), (35, 18), (36, 46), (5,  7 ),
     (5,  36), (7,  32), (7,  11), (7,  14), (11, 40), (11, 50), (22, 46),
     (28, 43), (28, 8 ), (32, 28), (32, 39), (32, 42), (40, 22), (40, 47),
     (43, 11), (43, 17)
    ]
 
windowSize :: (Int, Int)
windowSize = (640, 480)
 
fromEdges :: StdGen -> [Edge] -> Scene
fromEdges gen es =
    foldr scAddEdge (fst (Set.foldr' addv (emptyScene, gen) vs)) es
  where
    vs = Set.fromList (concat [[v1, v2] | (v1, v2) <- es])
 
    halfWidth  = fromIntegral (fst windowSize) / 2
    halfHeight = fromIntegral (snd windowSize) / 2
 
    addv v (sc, gen1) =
        let (x, gen2) = randomR (-halfWidth,  halfWidth ) gen1
            (y, gen3) = randomR (-halfHeight, halfHeight) gen2
        in  (scAddVertex v (x, y) sc, gen3)
 
sceneWindow :: Scene -> IO ()
sceneWindow sc =
    play (InWindow "Graph Drawing - ctrl + left mouse button to drag" windowSize (10, 10))
         black 30 sc drawScene handleEvent updatePositions
 
main :: IO ()
main =
    do gen <- getStdGen
       sceneWindow (fromEdges gen sampleGraph)
Судя по ошибке проблемы с областью видимости. Я пытался корректировать пробелы, но это не изменило ситуацию.
Копипастил и соединял код от сюда: https://mazzo.li/posts/graph-drawing.html

Помогите решить проблему, пожалуйста.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.05.2018, 04:30
Ответы с готовыми решениями:

Ошибка variable is already defined in the scope
Задумка была такой : создать базовый класс с полями,геттерами,сеттерами,потом создать...

A local variable named 'n' is already defined in this scope
Приветствую. Что за тут ошибка, можете помочь? Результат компилирования: Compilation failed: 1...

Возникает ошибка Error 1 A local variable named 'c' cannot be declared in this scope because it would give a different m
using System; using System.Collections.Generic; using System.Linq; using System.Text; ...

Список с дробями: Variable or field 'input' declared void 'pd' was not declared in this scope
почему не нравится 1ая функция? #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; struct rational_fraction...

10
Модератор
5047 / 3276 / 526
Регистрация: 01.06.2013
Сообщений: 6,806
Записей в блоге: 9
25.05.2018, 06:37 2
Если вы привели все сообщения и ghci не сообщает что Graphics.Gloss не найден, значит вы пакет gloss установили.
Не знаю какой версии и откуда. Если ставили stack-ом, то на stackage.org в этом пакете функция applyViewPortToPicture есть. Но, возможно, нужно добавить
Haskell
1
import Graphics.Gloss.Data.ViewPort
Скорее всего, потому что версия gloss изменилась с момента написания статьи.
Посмотрите аналогично на stackage.org по другим не найденным функциям.
1
5 / 5 / 1
Регистрация: 20.09.2015
Сообщений: 86
25.05.2018, 09:17  [ТС] 3
KolodeznyDiver, да, я показал все сообщения.

Спасибо, этот импорт почти помог, осталось только 2 ошибки..

Код
GHCi, version 8.2.2: http://www.haskell.org/ghc/  :? for help
Prelude> :l C:\Users\Egor\Documents\HaskellCoursework\Main.hs
[1 of 1] Compiling Main             ( C:\Users\Egor\Documents\HaskellCoursework\Main.hs, interpreted )

C:\Users\Egor\Documents\HaskellCoursework\Main.hs:91:61: error:
    Variable not in scope: graphEdges :: Graph -> Set Edge
   |
91 |     edges    = Pictures [drawEdge e sc   | e <- Set.toList (graphEdges gr)]
   |                                                             ^^^^^^^^^^

C:\Users\Egor\Documents\HaskellCoursework\Main.hs:101:40: error:
    * Variable not in scope: normaliseV :: Point -> Vector
    * Perhaps you meant `normalizeV' (imported from Graphics.Gloss.Data.Vector)
    |
101 |     if l > 0 then (charge / l) `mulSV` normaliseV d else 0
    |                                        ^^^^^^^^^^
Failed, no modules loaded.
Prelude>
Stack'ом я еще не пользовался. При первой попытке открыть в интерпретаторе конечно же полетели ошибки о том, что нет некоторых модулей. Я вручную скачал .tar.gz пакеты с этими модулями и соответствующие папки переместил в ghc
Код
C:\Program Files\Haskell Platform\8.2.2\lib\base-4.10.1.0
Поиск на stackage и на hoogle оставшихся 2х функций не дал результатов, какие еще можно применить фокусы?(
0
Модератор
5047 / 3276 / 526
Регистрация: 01.06.2013
Сообщений: 6,806
Записей в блоге: 9
25.05.2018, 09:47 4
Цитата Сообщение от Drovosek01 Посмотреть сообщение
Поиск на stackage и на hoogle оставшихся 2х функций не дал результатов, какие еще можно применить фокусы?(
Вставить код функции graphEdges из приведённой вами статьи.
normalizeV же написана неправильно, о чём вам компилятор и говорит предлагая правильное написание. Посмотрите внимательно.

Цитата Сообщение от Drovosek01 Посмотреть сообщение
Я вручную скачал .tar.gz пакеты с этими модулями и соответствующие папки переместил в ghc
Так не делают. Дальше тоже проблемы будут. Снесите платформу и установите стек.
Правильная установка Haskell. Утилита Stack
1
5 / 5 / 1
Регистрация: 20.09.2015
Сообщений: 86
25.05.2018, 10:05  [ТС] 5
KolodeznyDiver, заменил на normolize, теперь такие ошибки полезли:

Код
C:\Users\Egor\Documents\HaskellCoursework\Main.hs:91:61: error:
    Variable not in scope: graphEdges :: Graph -> Set Edge
   |
91 |     edges    = Pictures [drawEdge e sc   | e <- Set.toList (graphEdges gr)]
   |                                                             ^^^^^^^^^^

C:\Users\Egor\Documents\HaskellCoursework\Main.hs:103:9: error:
    * No instance for (Num Point) arising from a use of `-'
    * In the expression: v1 - v2
      In an equation for `d': d = v1 - v2
      In an equation for `pushForce':
          pushForce v1 v2
            = if l > 0 then (charge / l) `mulSV` normalizeV d else 0
            where
                d = v1 - v2
                l = magV d ** 2
    |
103 |     d = v1 - v2
    |         ^^^^^^^

C:\Users\Egor\Documents\HaskellCoursework\Main.hs:110:38: error:
    * No instance for (Num Point) arising from a use of `-'
    * In the second argument of `mulSV', namely `(v2 - v1)'
      In the expression: stiffness `mulSV` (v2 - v1)
      In an equation for `pullForce':
          pullForce v1 v2 = stiffness `mulSV` (v2 - v1)
    |
110 | pullForce v1 v2 = stiffness `mulSV` (v2 - v1)
    |                                      ^^^^^^^

C:\Users\Egor\Documents\HaskellCoursework\Main.hs:127:35: error:
    * No instance for (Num Vector) arising from a use of `+'
    * In the expression: (getVel pushForce v2pos +)
      In the first argument of Map.foldr', namely
        `(\ v2pos -> (getVel pushForce v2pos +))'
      In the expression:
        Map.foldr' (\ v2pos -> (getVel pushForce v2pos +)) 0 pts
    |
127 |     push = Map.foldr' (\v2pos -> (getVel pushForce v2pos +)) 0 pts
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^

C:\Users\Egor\Documents\HaskellCoursework\Main.hs:128:30: error:
    * No instance for (Num Vector) arising from a use of `+'
    * In the expression: (getVel pullForce v2pos +)
      In the first argument of `foldr', namely
        `(\ v2pos -> (getVel pullForce v2pos +))'
      In the expression:
        foldr
          (\ v2pos -> (getVel pullForce v2pos +))
          0
          [vertexPos v2 sc | v2 <- Set.toList (vertexNeighs v1 gr)]
    |
128 |     pull = foldr (\v2pos -> (getVel pullForce v2pos +)) 0
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.
0
Модератор
5047 / 3276 / 526
Регистрация: 01.06.2013
Сообщений: 6,806
Записей в блоге: 9
25.05.2018, 10:18 6
Drovosek01, Вставить код функции graphEdges из приведённой вами статьи. Забыли оттуда вставить.
1
5 / 5 / 1
Регистрация: 20.09.2015
Сообщений: 86
25.05.2018, 11:35  [ТС] 7
KolodeznyDiver, спасибо. А как исправить "No instance for..."?
0
Модератор
5047 / 3276 / 526
Регистрация: 01.06.2013
Сообщений: 6,806
Записей в блоге: 9
25.05.2018, 12:12 8
Лучший ответ Сообщение было отмечено Drovosek01 как решение

Решение

Цитата Сообщение от Drovosek01 Посмотреть сообщение
А как исправить "No instance for..."?
Не знаю куда инстанс делся. Проще написать. В начало файла вставляете
Haskell
1
{-# LANGUAGE FlexibleInstances #-}
А после импортов
Haskell
1
2
3
4
5
6
7
instance Num (Float, Float) where
  (xl,yl) + (xr,yr) = (xl+xr,yl+yr)
  (xl,yl) - (xr,yr) = (xl-xr,yl-yr)
  (xl,yl) * (xr,yr) = undefined
  fromInteger n = (fromInteger n,0)
  abs (x,y) = undefined
  signum (x,y) = undefined
Некоторые функции я не дописал (undefined), если понадобятся, напишите по аналогии.
1
5 / 5 / 1
Регистрация: 20.09.2015
Сообщений: 86
25.05.2018, 12:13  [ТС] 9
KolodeznyDiver, вставил код сразу после импортов, теперь он ругается на нелегальный instance.

Код
C:\Users\Egor\Documents\HaskellCoursework\WindowProg.hs:15:10: error:
    * Illegal instance declaration for `Num (Float, Float)'
        (All instance types must be of the form (T a1 ... an)
         where a1 ... an are *distinct type variables*,
         and each type variable appears at most once in the instance head.
         Use FlexibleInstances if you want to disable this.)
    * In the instance declaration for `Num (Float, Float)'
   |
15 | instance Num (Float, Float) where
   |          ^^^^^^^^^^^^^^^^^^
Вот код файла:
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Set (Set)
import qualified Data.Set as Set
import System.Random
 
import Graphics.Gloss
import Graphics.Gloss.Data.Vector
import Graphics.Gloss.Data.ViewState
import Graphics.Gloss.Interface.Pure.Game
import Graphics.Gloss.Data.ViewPort
 
{-# LANGUAGE FlexibleInstances #-}
 
instance Num (Float, Float) where
  (xl,yl) + (xr,yr) = (xl+xr,yl+yr)
  (xl,yl) - (xr,yr) = (xl-xr,yl-yr)
  (xl,yl) * (xr,yr) = undefined
  fromInteger n = (fromInteger n,0)
  abs (x,y) = undefined
  signum (x,y) = undefined
 
type Vertex = Int
type Edge = (Vertex, Vertex)
-- INVARIANT Every `Vertex` present in a set of neighbours is
-- present as a key in the `Map`.
newtype Graph = Graph {grNeighs :: Map Vertex (Set Vertex)}
 
emptyGraph :: Graph
emptyGraph = Graph Map.empty
 
addVertex :: Vertex -> Graph -> Graph
addVertex v (Graph neighs) =
    Graph $ case Map.lookup v neighs of
                Nothing -> Map.insert v Set.empty neighs
                Just _  -> neighs
 
addEdge :: Edge -> Graph -> Graph
addEdge (v1, v2) gr = Graph neighs
  where
    gr'    = addVertex v1 (addVertex v2 gr)
    neighs = Map.insert v1 (Set.insert v2 (vertexNeighs v1 gr')) $
             Map.insert v2 (Set.insert v1 (vertexNeighs v2 gr')) $
             grNeighs gr'
 
vertexNeighs :: Vertex -> Graph -> Set Vertex
vertexNeighs v (Graph neighs) = neighs Map.! v
 
graphEdges :: Graph -> Set Edge
graphEdges = Map.foldrWithKey' foldNeighs Set.empty . grNeighs
  where
    -- For each vertex `v1`, insert an edge for each neighbour `v2`.
    foldNeighs v1 ns es =
         Set.foldr' (\v2 -> Set.insert (order (v1, v2))) es ns
    order (v1, v2) = if v1 > v2 then (v1, v2) else (v2, v1)
-- INVARIANT The keys in `scGraph` are the same as the keys
-- in `scPoints`.
data Scene =
    Scene { scGraph     :: Graph
          , scPoints    :: Map Vertex Point
          , scSelected  :: Maybe Vertex
          , scViewState :: ViewState }
 
emptyScene :: Scene
emptyScene =
    Scene{ scGraph     = emptyGraph
         , scPoints    = Map.empty
         , scSelected  = Nothing
         , scViewState = viewStateInit }
 
scAddVertex :: Vertex -> Point -> Scene -> Scene
scAddVertex v pt sc@Scene{scGraph = gr, scPoints = pts} =
    sc{scGraph = addVertex v gr, scPoints = Map.insert v pt pts}
 
scAddEdge :: Edge -> Scene -> Scene
scAddEdge e@(v1, v2) sc@Scene{scGraph = gr, scPoints = pts} =
    if Map.member v1 pts && Map.member v2 pts
    then sc{scGraph = addEdge e gr}
    else error "scAddEdge: non existant point!"
 
vertexPos :: Vertex -> Scene -> Point
vertexPos v Scene{scPoints = pts} = pts Map.! v
 
vertexRadius :: Float
vertexRadius = 6
 
vertexColor :: Color
vertexColor = makeColor 1 0 0 1 -- Red
 
edgeColor :: Color
edgeColor = makeColor 1 1 1 0.8 -- Whiteish
 
drawVertex :: Vertex -> Scene -> Picture
drawVertex v sc =
    Translate x y (ThickCircle (vertexRadius / 2) vertexRadius)
  where (x, y) = vertexPos v sc
 
drawEdge :: Edge -> Scene -> Picture
drawEdge (v1, v2) sc = Line [vertexPos v1 sc, vertexPos v2 sc]
 
drawScene :: Scene -> Picture
drawScene sc@Scene{scGraph = gr, scViewState = ViewState{viewStateViewPort = port}} =
    applyViewPortToPicture port $
    Pictures [Color edgeColor edges, Color vertexColor vertices]
  where
    vertices = Pictures [drawVertex n sc | n <- Map.keys (grNeighs gr)    ]
    edges    = Pictures [drawEdge e sc   | e <- Set.toList (graphEdges gr)]
 
charge :: Float
charge = 100000
 
pushForce :: Point         -- Vertex we're calculating the force for
          -> Point         -- Vertex pushing the other away
          -> Vector
pushForce v1 v2 =
    -- If we are analysing the same vertex, l = 0
    if l > 0 then (charge / l) `mulSV` normalizeV d else 0
  where
    d = v1 - v2
    l = magV d ** 2
 
stiffness :: Float
stiffness = 1 / 2
 
pullForce :: Point -> Point -> Vector
pullForce v1 v2 = stiffness `mulSV` (v2 - v1)
 
updatePosition :: Float       -- Time since the last update
               -> Vertex      -- Vertex we are analysing
               -> Scene
               -> Point       -- New position
updatePosition dt v1 sc@Scene{scPoints = pts, scGraph = gr} =
    v1pos + pull + push
  where
    v1pos  = vertexPos v1 sc
 
    -- Gets a velocity by multiplying the time by the force (we take
    -- the mass to be 1).
    getVel f v2pos = dt `mulSV` f v1pos v2pos
 
    -- Sum all the pushing and pulling.  All the other vertices push,
    -- the connected vertices pull.
    push = Map.foldr' (\v2pos -> (getVel pushForce v2pos +)) 0 pts
    pull = foldr (\v2pos -> (getVel pullForce v2pos +)) 0
                 [vertexPos v2 sc | v2 <- Set.toList (vertexNeighs v1 gr)]
 
updatePositions :: Float -> Scene -> Scene
updatePositions dt sc@Scene{scSelected = sel, scGraph = Graph neighs} =
    foldr f sc (Map.keys neighs)
  where
    f n sc' =
        let pt = if Just n == sel
                 then vertexPos n sc else updatePosition dt n sc'
        in scAddVertex n pt sc'
 
inCircle :: Point             -- Where the user has clicked
         -> Float             -- The scaling factor in the ViewPort
         -> Point             -- The position of the vertex
         -> Bool
inCircle p sca v = magV (v - p) <= vertexRadius * sca
 
findVertex :: Point -> Float -> Scene -> Maybe Vertex
findVertex p1 sca Scene{scPoints = pts} =
    Map.foldrWithKey' f Nothing pts
  where
    f _ _  (Just v) = Just v
    f v p2 Nothing  = if inCircle p1 sca p2 then Just v else Nothing
 
handleEvent :: Event -> Scene -> Scene
 
handleEvent (EventKey (MouseButton LeftButton) Down Modifiers{ctrl = Down} pos) sc =
    case findVertex (invertViewPort port pos) (viewPortScale port) sc of
        Nothing -> sc
        Just v  -> sc{scSelected = Just v}
  where
    viewState = scViewState sc
    port      = viewStateViewPort viewState
 
handleEvent (EventKey (MouseButton LeftButton) Up _ _) sc@Scene{scSelected = Just _} =
    sc{scSelected = Nothing}
 
handleEvent (EventMotion pos) sc@Scene{scPoints = pts, scSelected = Just v} =
    sc{scPoints = Map.insert v (invertViewPort port pos) pts}
 where
   port = viewStateViewPort (scViewState sc)
 
handleEvent ev sc =
    sc{scViewState = updateViewStateWithEvent ev (scViewState sc)}
 
-- Taken from <http://www.graphviz.org/Gallery/undirected/transparency.gv.txt>.
sampleGraph :: [Edge]
sampleGraph =
    [(1,  30), (1,  40), (8,  46), (8,  16), (10, 25), (10, 19), (10, 33),
     (12, 8 ), (12, 36), (12, 17), (13, 38), (13, 24), (24, 49), (24, 13),
     (24, 47), (24, 12), (25, 27), (25, 12), (27, 12), (27, 14), (29, 10),
     (29, 8 ), (30, 24), (30, 44), (38, 29), (38, 35), (2,  42), (2,  35),
     (2,  11), (14, 18), (14, 24), (14, 38), (18, 49), (18, 47), (26, 41),
     (26, 42), (31, 39), (31, 47), (31, 25), (37, 26), (37, 16), (39, 50),
     (39, 14), (39, 18), (39, 47), (41, 31), (41, 8 ), (42, 44), (42, 29),
     (44, 37), (44, 32), (3,  20), (3,  28), (6,  45), (6,  28), (9,  6 ),
     (9,  16), (15, 16), (15, 48), (16, 50), (16, 32), (16, 39), (20, 33),
     (33, 9 ), (33, 46), (33, 48), (45, 15), (4,  17), (4,  15), (4,  12),
     (17, 21), (19, 35), (19, 15), (19, 43), (21, 19), (21, 50), (23, 36),
     (34, 23), (34, 24), (35, 34), (35, 16), (35, 18), (36, 46), (5,  7 ),
     (5,  36), (7,  32), (7,  11), (7,  14), (11, 40), (11, 50), (22, 46),
     (28, 43), (28, 8 ), (32, 28), (32, 39), (32, 42), (40, 22), (40, 47),
     (43, 11), (43, 17)
    ]
 
windowSize :: (Int, Int)
windowSize = (640, 480)
 
fromEdges :: StdGen -> [Edge] -> Scene
fromEdges gen es =
    foldr scAddEdge (fst (Set.foldr' addv (emptyScene, gen) vs)) es
  where
    vs = Set.fromList (concat [[v1, v2] | (v1, v2) <- es])
 
    halfWidth  = fromIntegral (fst windowSize) / 2
    halfHeight = fromIntegral (snd windowSize) / 2
 
    addv v (sc, gen1) =
        let (x, gen2) = randomR (-halfWidth,  halfWidth ) gen1
            (y, gen3) = randomR (-halfHeight, halfHeight) gen2
        in  (scAddVertex v (x, y) sc, gen3)
 
sceneWindow :: Scene -> IO ()
sceneWindow sc =
    play (InWindow "Graph Drawing - ctrl + left mouse button to drag" windowSize (10, 10))
         black 30 sc drawScene handleEvent updatePositions
 
main :: IO ()
main =
    do gen <- getStdGen
       sceneWindow (fromEdges gen sampleGraph)
0
Модератор
5047 / 3276 / 526
Регистрация: 01.06.2013
Сообщений: 6,806
Записей в блоге: 9
25.05.2018, 12:30 10
Drovosek01, {-# LANGUAGE FlexibleInstances #-} сделайте первой строкой.
2
5 / 5 / 1
Регистрация: 20.09.2015
Сообщений: 86
25.05.2018, 14:06  [ТС] 11
KolodeznyDiver, большое спасибо! Всё заработало.
В ghci импортировал модуль с этим кодом, потом вызвал функцию main и открылось окно с подвижным графом. (конечно костыль лютый, но мне пока пойдёт)
Миниатюры
Variable not in scope  
1
25.05.2018, 14:06
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.05.2018, 14:06
Помогаю со студенческими работами здесь

Request scope или Session scope
Всем привет Столкнулся с проблемой хранения данных. У меня есть страница которая отображает список...

Можно ли в yii соединить (смержить) scope текущего класса со scope класса родителя?
Добрый день, Например есть: class ActiveRecord extends CActiveRecord { ... return ...

'arr' was not declared in this scope 'sum' was not declared in this scope такие вот ошибки.(
#include &lt;iostream&gt; #include &lt;cstdlib&gt; #include &lt;ctime&gt; using namespace std; int main () { ...

Ошибка 'Run-time error '91': Oject variable or with block variable not set'
Здравствуйте. :) Я пользуюсь Вижуал Базик версии 5.0 и столкнулся вот с какой проблемой....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru