F# 编译器无法解析共享';标题';文件
共同点。fs:F# 编译器无法解析共享';标题';文件,f#,F#,共同点。fs: namespace Bug module Common = type SourceEntity = { id : int link : string } type ReleaseEntity = { id : int notes : string } 在Release.fs中 namespace Bug open System open Common module Release =
namespace Bug
module Common =
type SourceEntity = {
id : int
link : string
}
type ReleaseEntity = {
id : int
notes : string
}
在Release.fs中
namespace Bug
open System
open Common
module Release =
let cache = new Collections.Generic.Dictionary<int, ReleaseEntity>()
let AddToCache(entity) =
cache.Add(entity.id, entity)
()
let AddRec() =
let entity : ReleaseEntity = {
id = 1
notes = "Notes"
}
AddToCache(entity)
namespace Bug
open System
open Common
module Source =
let Cache = new Collections.Generic.Dictionary<int, SourceEntity>()
let AddToCache(entity) =
Cache.Add(entity.id, entity) <<=== E R R O R
()
let AddRec() =
let ent : SourceEntity = {
id = 1
releases = "Releases"
}
AddToCache(ent) <<=== E R R O R
名称空间错误
开放系统
开放式公用
模块释放=
let cache=new Collections.Generic.Dictionary()
让AddToCache(实体)=
cache.Add(entity.id,entity)
()
let AddRec()=
let实体:ReleaseEntity={
id=1
notes=“notes”
}
AddToCache(实体)
在Source.fs中
namespace Bug
open System
open Common
module Release =
let cache = new Collections.Generic.Dictionary<int, ReleaseEntity>()
let AddToCache(entity) =
cache.Add(entity.id, entity)
()
let AddRec() =
let entity : ReleaseEntity = {
id = 1
notes = "Notes"
}
AddToCache(entity)
namespace Bug
open System
open Common
module Source =
let Cache = new Collections.Generic.Dictionary<int, SourceEntity>()
let AddToCache(entity) =
Cache.Add(entity.id, entity) <<=== E R R O R
()
let AddRec() =
let ent : SourceEntity = {
id = 1
releases = "Releases"
}
AddToCache(ent) <<=== E R R O R
名称空间错误
开放系统
开放式公用
模块源=
let Cache=new Collections.Generic.Dictionary()
让AddToCache(实体)=
Cache.Add(entity.id,entity)当您遇到类型错误时,请尝试思考编译器是如何推断特定类型的
在这里:
编译器是否可以知道哪种类型在实体
中有一个id
字段?
如果你输入了
let entity = { id = 1; link = "" }
编译器会推断这是SourceEntity
,因为只有SourceEntity
具有这些特定的记录字段。在cache.Add(entity.id,entity)
中,编译器除了必须有id
字段外,没有其他约束,因此它会选择最后一个匹配的类型-这就是为什么会出现错误
如果将公共id字段重构为
namespace Bug
module Common =
type SourceEntity = {
source_id : int
link : string
}
type ReleaseEntity = {
release_id : int
notes : string
}
你会发现错误消失了
解决方案
namespace Bug
open System
open Common
module Release =
let cache = new Collections.Generic.Dictionary<int, ReleaseEntity>()
let AddToCache(entity) =
cache.Add(entity.id, entity)
()
let AddRec() =
let entity : ReleaseEntity = {
id = 1
notes = "Notes"
}
AddToCache(entity)
namespace Bug
open System
open Common
module Source =
let Cache = new Collections.Generic.Dictionary<int, SourceEntity>()
let AddToCache(entity) =
Cache.Add(entity.id, entity) <<=== E R R O R
()
let AddRec() =
let ent : SourceEntity = {
id = 1
releases = "Releases"
}
AddToCache(ent) <<=== E R R O R
所有解决方案都涉及将其约束为已知类型
最简单的方法是添加类型注释:
let AddToCache(entity: SourceEntity) =
let AddToCache(entity) =
Cache.Add(entity.id, entity)
()
另一个是明确地解构它:
let { SourceEntity.id = id } = entity
Cache.Add(id, entity)
另一种方法是强制类型-这与此处无关,但在以后可能会很有用:
Cache.Add((entity :> SourceEntity).id, entity)
我建议从F#for fun and profit on type inference那里获得一个很好的过程解释
p.S.
实际上,您只需要一个类型注释。
其余的可以推断:)
模块源代码=
let Cache=new Collections.Generic.Dictionary()
let AddToCache(实体:SourceEntity)=
Cache.Add(entity.id,entity)
()
让AddRec()=
让ent={
id=1
link=“”
}
AddToCache(耳鼻喉科)
当您遇到类型错误时,请尝试思考编译器是如何推断出特定类型的
在这里:
编译器是否可以知道哪种类型在实体
中有一个id
字段?
如果你输入了
let entity = { id = 1; link = "" }
编译器会推断这是SourceEntity
,因为只有SourceEntity
具有这些特定的记录字段。在cache.Add(entity.id,entity)
中,编译器除了必须有id
字段外,没有其他约束,因此它会选择最后一个匹配的类型-这就是为什么会出现错误
如果将公共id字段重构为
namespace Bug
module Common =
type SourceEntity = {
source_id : int
link : string
}
type ReleaseEntity = {
release_id : int
notes : string
}
你会发现错误消失了
解决方案
namespace Bug
open System
open Common
module Release =
let cache = new Collections.Generic.Dictionary<int, ReleaseEntity>()
let AddToCache(entity) =
cache.Add(entity.id, entity)
()
let AddRec() =
let entity : ReleaseEntity = {
id = 1
notes = "Notes"
}
AddToCache(entity)
namespace Bug
open System
open Common
module Source =
let Cache = new Collections.Generic.Dictionary<int, SourceEntity>()
let AddToCache(entity) =
Cache.Add(entity.id, entity) <<=== E R R O R
()
let AddRec() =
let ent : SourceEntity = {
id = 1
releases = "Releases"
}
AddToCache(ent) <<=== E R R O R
所有解决方案都涉及将其约束为已知类型
最简单的方法是添加类型注释:
let AddToCache(entity: SourceEntity) =
let AddToCache(entity) =
Cache.Add(entity.id, entity)
()
另一个是明确地解构它:
let { SourceEntity.id = id } = entity
Cache.Add(id, entity)
另一种方法是强制类型-这与此处无关,但在以后可能会很有用:
Cache.Add((entity :> SourceEntity).id, entity)
我建议从F#for fun and profit on type inference那里获得一个很好的过程解释
p.S.
实际上,您只需要一个类型注释。
其余的可以推断:)
模块源代码=
let Cache=new Collections.Generic.Dictionary()
let AddToCache(实体:SourceEntity)=
Cache.Add(entity.id,entity)
()
让AddRec()=
让ent={
id=1
link=“”
}
AddToCache(耳鼻喉科)
这是记录字段名称的冲突(和阴影)
当您在Bug.Source.AddToCache
的主体中写入entity.id
时,编译器使用您正在访问.id
字段的事实来推断entity
的类型。哪些记录的字段名为id
?这两条记录确实如此,但编译器必须选择一条。怎么用?简单:最后一个优先。这被称为“阴影”
为了消除选择的歧义,只需添加一个类型注释:
let AddToCache(entity: SourceEntity) =
let AddToCache(entity) =
Cache.Add(entity.id, entity)
()
等等,但是为什么编译器不使用缓存的类型。添加来推断实体的类型
嗯,这只是F#的一个限制(或特征?)。编译是单遍的,类型干涉自上而下、从左到右进行,没有双回。这使得编译器能够非常快速且非常可预测(看看你,Haskell)
但在这种情况下,这意味着当编译器看到实体
被用作缓存.Add
中的参数时,它已经决定了它必须是什么类型。这是记录字段名的冲突(和阴影)
当您在Bug.Source.AddToCache
的主体中写入entity.id
时,编译器使用您正在访问.id
字段的事实来推断entity
的类型。哪些记录的字段名为id
?这两条记录确实如此,但编译器必须选择一条。怎么用?简单:最后一个优先。这被称为“阴影”
为了消除选择的歧义,只需添加一个类型注释:
let AddToCache(entity: SourceEntity) =
let AddToCache(entity) =
Cache.Add(entity.id, entity)
()
等等,但是为什么编译器不使用缓存的类型。添加来推断实体的类型
嗯,这只是F#的一个限制(或特征?)。编译是单遍的,类型干涉自上而下、从左到右进行,没有双回。这使得编译器能够非常快速且非常可预测(看看你,Haskell)
但在这种情况下,这意味着当编译器看到实体
被用作缓存中的参数时,它已经决定了它的类型必须是什么。谢谢。我并没有完全意识到